tizen 2.3.1 release
[framework/uifw/cbhm.git] / 2.3-mobile / src / storage.c
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *  Licensed under the Apache License, Version 2.0 (the "License");
5  *  you may not use this file except in compliance with the License.
6  *  You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *  Unless required by applicable law or agreed to in writing, software
11  *  distributed under the License is distributed on an "AS IS" BASIS,
12  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *  See the License for the specific language governing permissions and
14  *  limitations under the License.
15  *
16  */
17
18 #include <Ecore_File.h>
19
20 #include "storage.h"
21 #define STORAGE_FILEPATH "/opt/var/.cbhm_data"
22 #define STORAGE_KEY_INDEX_FORMAT "<index%02d>"
23 #define STORAGE_KEY_ITEM_FORMAT "<item%02d%s>"
24 #define STORAGE_INDEX_ITEM_NONE 0.0
25
26 static Eina_Bool item_write(Eet_File *ef, int index, CNP_ITEM *item);
27 static Eina_Bool item_delete(Eet_File *ef, int index);
28 static Eina_Bool storage_index_write(StorageData *sd, int index);
29 static Eina_Bool storage_item_write(AppData *ad, CNP_ITEM *item);
30 static Eina_Bool storage_item_delete(AppData *ad, CNP_ITEM *item);
31 static Eina_Bool storage_item_update(AppData *ad, CNP_ITEM *item);
32 static CNP_ITEM *storage_item_load(StorageData *sd, int index);
33 //static void dump_items(StorageData *sd);
34
35 static int getMinIndex(indexType *indexTable, int len)
36 {
37         int i = 0;
38         int minIndex;
39         indexType min;
40         min = indexTable[i];
41         minIndex = i;
42
43         for (i = 1; i < len; i++)
44         {
45                 if ((min > indexTable[i]))
46                 {
47                         min = indexTable[i];
48                         minIndex = i;
49                 }
50         }
51         return minIndex;
52 }
53
54 static int getMaxIndex(indexType *indexTable, int len)
55 {
56         int i = 0;
57         indexType max = indexTable[i];
58         int maxIndex = i;
59         for (i = 1; i < len; i++)
60         {
61                 if (max < indexTable[i])
62                 {
63                         max = indexTable[i];
64                         maxIndex = i;
65                 }
66         }
67         return maxIndex;
68 }
69
70 StorageData *init_storage(AppData *ad)
71 {
72         CALLED();
73         StorageData *sd = CALLOC(1, sizeof(StorageData));
74         if (!sd) return EINA_FALSE;
75
76         eet_init();
77         ecore_file_init();
78
79         sd->ef = eet_open(STORAGE_FILEPATH, EET_FILE_MODE_READ_WRITE);
80
81         if (sd->ef)
82         {
83                 char datakey[20];
84                 int i, j;
85                 int index;
86                 int index_order[ITEM_CNT_MAX];
87                 int read_size;
88                 indexType *read_data;
89                 indexType temp[ITEM_CNT_MAX];
90
91                 // Initialize index data in file
92                 for (i = 0; i < ITEM_CNT_MAX; i++)
93                 {
94                         sd->itemTable[i] = NULL;
95                         sd->indexTable[i] = STORAGE_INDEX_ITEM_NONE;
96                 }
97
98                 // Load index data from file
99                 for (i = 0; i < ITEM_CNT_MAX; i++)
100                 {
101                         snprintf(datakey, sizeof(datakey), STORAGE_KEY_INDEX_FORMAT, i);
102                         read_data = eet_read(sd->ef, datakey, &read_size);
103                         if (read_data && read_size > 0)
104                                 temp[i] = atol((char *)read_data);
105                         else
106                                 temp[i] = STORAGE_INDEX_ITEM_NONE;
107                         free(read_data);
108                 }
109
110                 // Load item data from file
111                 for (i = 0, index = 0; i < ITEM_CNT_MAX; i++)
112                 {
113                         int maxIndex = getMaxIndex(temp, ITEM_CNT_MAX);
114                         if (temp[maxIndex] == STORAGE_INDEX_ITEM_NONE)
115                                 break;
116                         else
117                         {
118                                 sd->itemTable[maxIndex] = storage_item_load(sd, maxIndex);
119                                 sd->indexTable[maxIndex] = temp[maxIndex];
120                                 temp[maxIndex] = STORAGE_INDEX_ITEM_NONE;
121                                 index_order[index] = maxIndex;
122                                 index++;
123                         }
124                 }
125
126                 // Add loaded item to clipboard
127                 if (index > 0)
128                 {
129                         for (i = index - 1; i >= 0; i--)
130                         {
131                                 j = index_order[i];
132                                 if (sd->itemTable[j])
133                                         item_add_by_CNP_ITEM(ad, sd->itemTable[j], EINA_FALSE, EINA_FALSE);
134                         }
135                 }
136                 else
137                 {
138                         DBG("load storage index failed");
139                 }
140         }
141         else
142                 DBG("storage ef is NULL");
143
144         //dump_items(sd);
145
146         ad->storage_item_add = storage_item_write;
147         ad->storage_item_del = storage_item_delete;
148         ad->storage_item_load = storage_item_load;
149         ad->storage_item_update = storage_item_update;
150
151         return sd;
152 }
153
154 void depose_storage(StorageData *sd)
155 {
156         CALLED();
157         //dump_items(sd);
158         if (sd->ef)
159                 eet_close(sd->ef);
160         sd->ef = NULL;
161         eet_shutdown();
162         ecore_file_shutdown();
163 }
164 /*
165 static void dump_items(StorageData *sd)
166 {
167         CALLED();
168         int i;
169         for (i = 0; i < ITEM_CNT_MAX; i++)
170         {
171                 CNP_ITEM *item = storage_item_load(sd, i);
172                 if (item)
173                         DBG("item #%d type_index: 0x%x, gitem_style: 0x%x, data: %s\n, len: %d\n, file: %s\n, file_len: %d\n", i, item->type_index, item->gitem_style, (char *)item->data, item->len, (char *)item->file, item->file_len);
174                 free(item);
175         }
176 }
177 */
178 static Eina_Bool item_write(Eet_File *ef, int index, CNP_ITEM *item)
179 {
180         if (!ef)
181         {
182                 ERR("eet_file is NULL");
183                 return EINA_FALSE;
184         }
185         if (!item)
186         {
187                 ERR("item is NULL");
188                 return EINA_FALSE;
189         }
190
191         Eina_Bool ret = EINA_FALSE;
192         char datakey[20];
193         char write_data[10];
194
195         if (item->len > 0) {
196                 snprintf(datakey, sizeof(datakey), STORAGE_KEY_ITEM_FORMAT, index, "data");
197                 ret = eet_write(ef, datakey, item->data, item->len, 1);
198         }
199
200         if (item->file_len > 0) {
201                 snprintf(datakey, sizeof(datakey), STORAGE_KEY_ITEM_FORMAT, index, "file");
202                 ret &= eet_write(ef, datakey, item->file, item->file_len, 1);
203         }
204
205         snprintf(datakey, sizeof(datakey), STORAGE_KEY_ITEM_FORMAT, index, "type_index");
206         snprintf(write_data, sizeof(write_data), "%d", item->type_index);
207         ret &= eet_write(ef, datakey, write_data, strlen(write_data) + 1, 1);
208
209         snprintf(datakey, sizeof(datakey), STORAGE_KEY_ITEM_FORMAT, index, "gitem_style");
210         snprintf(write_data, sizeof(write_data), "%d", item->gitem_style);
211         ret &= eet_write(ef, datakey, write_data, strlen(write_data) + 1, 1);
212
213         snprintf(datakey, sizeof(datakey), STORAGE_KEY_ITEM_FORMAT, index, "locked");
214         snprintf(write_data, sizeof(write_data), "%d", item->locked);
215         ret &= eet_write(ef, datakey, write_data, strlen(write_data) + 1, 1);
216
217         eet_sync(ef);
218         DBG("write result: %d, item index: %d", ret, index);
219
220         return ret != 0;
221 }
222
223 static Eina_Bool item_delete(Eet_File *ef, int index)
224 {
225         if (!ef)
226         {
227                 ERR("eet_file is NULL");
228                 return EINA_FALSE;
229         }
230
231         Eina_Bool ret;
232         char datakey[20];
233
234         snprintf(datakey, sizeof(datakey), STORAGE_KEY_ITEM_FORMAT, index, "data");
235         ret = eet_delete(ef, datakey);
236
237         snprintf(datakey, sizeof(datakey), STORAGE_KEY_ITEM_FORMAT, index, "type_index");
238         ret &= eet_delete(ef, datakey);
239
240         snprintf(datakey, sizeof(datakey), STORAGE_KEY_ITEM_FORMAT, index, "gitem_style");
241         ret &= eet_delete(ef, datakey);
242
243         snprintf(datakey, sizeof(datakey), STORAGE_KEY_ITEM_FORMAT, index, "locked");
244         ret &= eet_delete(ef, datakey);
245
246         eet_sync(ef);
247         DBG("delete result: %d, item index: %d", ret, index);
248
249         return ret != 0;
250 }
251
252 static Eina_Bool storage_item_update(AppData *ad, CNP_ITEM *item)
253 {
254         CALLED();
255         StorageData *sd = ad->storage;
256         CNP_ITEM *temp;
257         Eina_Bool ret = EINA_FALSE;
258         int index;
259         char datakey[20];
260         char write_data[10];
261
262         if (!item)
263         {
264                 ERR("item is NULL");
265                 return EINA_FALSE;
266         }
267
268         for (index = 0; index < ITEM_CNT_MAX; index++)
269         {
270                 temp = sd->itemTable[index];
271
272                 if (temp &&
273                          (item->type_index == temp->type_index) &&
274                          (!SAFE_STRCMP(item->data, temp->data)))
275                         break;
276         }
277         //delete before value.
278         snprintf(datakey, sizeof(datakey), STORAGE_KEY_ITEM_FORMAT, index, "locked");
279         ret &= eet_delete(sd->ef, datakey);
280         eet_sync(sd->ef);
281
282         //rewrite locked value.
283         snprintf(datakey, sizeof(datakey), STORAGE_KEY_ITEM_FORMAT, index, "locked");
284         snprintf(write_data, sizeof(write_data), "%d", item->locked);
285         ret &= eet_write(sd->ef, datakey, write_data, strlen(write_data) + 1, 1);
286         eet_sync(sd->ef);
287
288         return ret != 0;
289
290 }
291
292 static Eina_Bool storage_item_write(AppData *ad, CNP_ITEM *item)
293 {
294         CALLED();
295         StorageData *sd = ad->storage;
296         CNP_ITEM *temp;
297         Eina_Bool ret = EINA_TRUE;
298         int index;
299
300         if (!item)
301         {
302                 ERR("item is NULL");
303                 return EINA_FALSE;
304         }
305
306         for (index = 0; index < ITEM_CNT_MAX; index++)
307         {
308                 temp = sd->itemTable[index];
309
310                 if (temp &&
311                          (item->type_index == temp->type_index) &&
312                          (!SAFE_STRCMP(item->data, temp->data)))
313                         break;
314         }
315
316         // Item does not exist in clipboard
317         if (index == ITEM_CNT_MAX)
318         {
319                 index = getMinIndex(sd->indexTable, ITEM_CNT_MAX);
320                 ret = item_write(sd->ef, index, item);
321         }
322
323         sd->indexTable[index] = ecore_time_unix_get();
324         sd->itemTable[index] = item;
325         ret &= storage_index_write(sd, index);
326         //dump_items(sd);
327         return ret;
328 }
329
330 static Eina_Bool storage_item_delete(AppData *ad, CNP_ITEM *item)
331 {
332         CALLED();
333         StorageData *sd = ad->storage;
334         Eina_Bool ret = EINA_FALSE;
335         int index;
336
337         for (index = 0; index < ITEM_CNT_MAX; index++)
338         {
339                 if (sd->itemTable[index] == item)
340                         break;
341         }
342
343         if (index < ITEM_CNT_MAX)
344         {
345                 ret = item_delete(sd->ef, index);
346                 sd->indexTable[index] = STORAGE_INDEX_ITEM_NONE;
347                 sd->itemTable[index] = NULL;
348                 ret &= storage_index_write(sd, index);
349         }
350         return ret;
351 }
352
353 static CNP_ITEM *storage_item_load(StorageData *sd, int index)
354 {
355         if (!sd->ef)
356         {
357                 ERR("eet_file is NULL");
358                 return NULL;
359         }
360         if (index >= ITEM_CNT_MAX)
361                 return NULL;
362
363         char datakey[20];
364         char *read_data;
365         int read_size;
366         CNP_ITEM *item = CALLOC(1, sizeof(CNP_ITEM));
367
368         if (!item) {
369                 ERR("item CALLOC failed");
370                 return NULL;
371         }
372
373         snprintf(datakey, sizeof(datakey), STORAGE_KEY_ITEM_FORMAT, index, "data");
374         read_data = eet_read(sd->ef, datakey, &read_size);
375         if (read_data){
376             if (read_size > 0) {
377                 item->len = read_size;
378                 item->data = CALLOC(1, read_size * sizeof(char));
379                         if (item->data) {
380                                 memcpy(item->data, read_data, read_size);
381                         }
382                         else {
383                                 free(read_data);
384                                 FREE(item);
385                                 return NULL;
386                         }
387             }
388             free(read_data);
389           }
390
391         snprintf(datakey, sizeof(datakey), STORAGE_KEY_ITEM_FORMAT, index, "file");
392         read_data = eet_read(sd->ef, datakey, &read_size);
393         if (read_data) {
394                 if (read_size > 0) {
395                 item->file_len = read_size;
396                 item->file = CALLOC(1, read_size * sizeof(char));
397                 if (item->file)
398                         memcpy(item->file, read_data, read_size);
399                 }
400                 free(read_data);
401         }
402
403         snprintf(datakey, sizeof(datakey), STORAGE_KEY_ITEM_FORMAT, index, "type_index");
404         read_data = eet_read(sd->ef, datakey, &read_size);
405         if (read_data) {
406                 if ( read_size > 0) {
407                 item->type_index = atoi(read_data);
408                 }
409                 free(read_data);
410         }
411
412         snprintf(datakey, sizeof(datakey), STORAGE_KEY_ITEM_FORMAT, index, "gitem_style");
413         read_data = eet_read(sd->ef, datakey, &read_size);
414         if (read_data) {
415                 if ( read_size > 0) {
416                 item->gitem_style = atoi(read_data);
417                 }
418                 free(read_data);
419         }
420
421         snprintf(datakey, sizeof(datakey), STORAGE_KEY_ITEM_FORMAT, index, "locked");
422         read_data = eet_read(sd->ef, datakey, &read_size);
423         if (read_data) {
424                 if (read_size > 0) {
425                 item->locked = atoi(read_data);
426                 }
427                 free(read_data);
428         }
429
430         return item;
431 }
432
433 static Eina_Bool storage_index_write(StorageData *sd, int index)
434 {
435         CALLED();
436         Eina_Bool ret;
437         char datakey[20];
438         char write_data[50];
439
440         if (!sd->ef)
441         {
442                 ERR("eet_file is NULL");
443                 return EINA_FALSE;
444         }
445
446         snprintf(datakey, sizeof(datakey), STORAGE_KEY_INDEX_FORMAT, index);
447         snprintf(write_data, sizeof(write_data), "%lf", sd->indexTable[index]);
448         ret = eet_write(sd->ef, datakey, write_data, strlen(write_data) + 1, 1);
449
450         eet_sync(sd->ef);
451
452         return ret != 0;
453 }