EFL 1.7 svn doobies
[profile/ivi/eina.git] / src / examples / eina_model_03.c
1 //Compile with:
2 //gcc -g eina_model_03.c -o eina_model_03 `pkg-config --cflags --libs eina`
3
4 #include <Eina.h>
5 #include <string.h>
6 #include <stdio.h>
7 #include <errno.h>
8
9 static Eina_Model_Type *ADDRESS_BOOK_TYPE;
10 static Eina_Model_Type *PERSON_TYPE;
11
12 static void address_book_init(void);
13
14 int main(void)
15 {
16    Eina_Model *address_book;
17    Eina_Value val;
18    int i, count;
19    char *s;
20
21    eina_init();
22
23    address_book_init();
24
25    address_book = eina_model_new(ADDRESS_BOOK_TYPE);
26
27    eina_value_setup(&val, EINA_VALUE_TYPE_STRING);
28    eina_value_set(&val, "addr_book.txt");
29    eina_model_property_set(address_book, "filename", &val);
30    eina_value_flush(&val);
31
32    eina_model_load(address_book);
33    s = eina_model_to_string(address_book);
34    printf("model as string:\n%s\n\n", s);
35    free(s);
36
37    count = eina_model_child_count(address_book);
38    printf("Address Book with %d entries:\n", count);
39    for (i = 0; i < count; i++)
40      {
41         Eina_Model *person = eina_model_child_get(address_book, i);
42         Eina_Value nameval, emailval;
43         const char *name, *email;
44
45         eina_model_property_get(person, "name", &nameval);
46         eina_model_property_get(person, "email", &emailval);
47
48         eina_value_get(&nameval, &name);
49         eina_value_get(&emailval, &email);
50
51         printf("%02d \"%s\" <%s>\n", i, name, email);
52
53         // We don't need property values anymore
54         eina_value_flush(&nameval);
55         eina_value_flush(&emailval);
56
57         // We don't need our reference to person anymore
58         eina_model_unref(person);
59      }
60
61    eina_model_unref(address_book);
62    eina_shutdown();
63
64    return 0;
65 }
66
67 // Structure Descriptions are just used internally in the type constructors:
68 static Eina_Value_Struct_Desc *ADDRESS_BOOK_DESC;
69 static Eina_Value_Struct_Desc *PERSON_DESC;
70
71 static Eina_Bool
72 _person_constructor(Eina_Model *model)
73 {
74    // call parent type constructor, like "super" in other languages:
75    if (!eina_model_type_constructor(EINA_MODEL_TYPE_STRUCT, model))
76      return EINA_FALSE;
77
78    // Do specific setup of our internal structure, letting it know about
79    // our description
80    return eina_model_struct_set(model, PERSON_DESC, NULL);
81 }
82
83 static Eina_Bool
84 _address_book_constructor(Eina_Model *model)
85 {
86    // call parent type constructor, like "super" in other languages:
87    if (!eina_model_type_constructor(EINA_MODEL_TYPE_STRUCT, model))
88      return EINA_FALSE;
89
90    // Do specific setup of our internal structure, letting it know about
91    // our description
92    return eina_model_struct_set(model, ADDRESS_BOOK_DESC, NULL);
93 }
94
95 static Eina_Bool
96 _address_book_load(Eina_Model *model)
97 {
98    const char *filename;
99    Eina_Value val;
100    char buf[256];
101    FILE *f;
102
103    // We retrieve filename from property of same name:
104    eina_model_property_get(model, "filename", &val);
105    eina_value_get(&val, &filename);
106
107    EINA_SAFETY_ON_NULL_RETURN_VAL(filename, EINA_FALSE);
108
109    f = fopen(filename, "r");
110
111    // Now that we have used filename, we must free its memory holder:
112    eina_value_flush(&val);
113
114    EINA_SAFETY_ON_NULL_RETURN_VAL(f, EINA_FALSE);
115
116    while (fgets(buf, sizeof(buf), f))
117      {
118         Eina_Model *person;
119         char *name, *email;
120
121         if (strlen(buf) <= 1)
122           continue;
123
124         name = strtok(buf, "\t");
125         email = strtok(NULL, "\n");
126
127         if ((!name) || (!email)) continue;
128
129         // Create person
130         person = eina_model_new(PERSON_TYPE);
131
132         // Setup value type as string, as our properties are strings:
133         eina_value_setup(&val, EINA_VALUE_TYPE_STRING);
134
135         // Set string properties:
136         eina_value_set(&val, name);
137         eina_model_property_set(person, "name", &val);
138
139         eina_value_set(&val, email);
140         eina_model_property_set(person, "email", &val);
141
142         // Flush value, free string
143         eina_value_flush(&val);
144
145         // Add person to the end of model children
146         eina_model_child_append(model, person);
147
148         // Model already holds its reference to person, we release ours
149         eina_model_unref(person);
150      }
151
152    fclose(f);
153    return EINA_TRUE;
154 }
155
156 static void
157 address_book_init(void)
158 {
159    // Declare type for internal struct, this is just used to easily
160    // create Eina_Value_Struct_Member array for Eina_Value_Struct_Desc.
161    //
162    // We don't need this structure outside address_book_init()
163    // as it is managed automatically by Eina_Value_Struct, used by
164    // Eina_Model_Struct! Handy! :-)
165    typedef struct _Person Person;
166    struct _Person
167    {
168       const char *name;
169       const char *email;
170    };
171    static Eina_Value_Struct_Member person_members[] = {
172      // no eina_value_type as they are not constant initializers, see below.
173      EINA_VALUE_STRUCT_MEMBER(NULL, Person, name),
174      EINA_VALUE_STRUCT_MEMBER(NULL, Person, email)
175    };
176    // Values that cannot be set on static declarations since they are not
177    // constant initializers. It is a nitpick from C that we need to deal with
178    // here and on all our other declarations.
179    person_members[0].type = EINA_VALUE_TYPE_STRING;
180    person_members[1].type = EINA_VALUE_TYPE_STRING;
181
182    static Eina_Value_Struct_Desc person_desc = {
183      EINA_VALUE_STRUCT_DESC_VERSION,
184      NULL, // no special operations
185      person_members,
186      EINA_C_ARRAY_LENGTH(person_members),
187      sizeof(Person)
188    };
189    static Eina_Model_Type person_type = EINA_MODEL_TYPE_INIT_NOPRIVATE
190      ("Person_Type",
191       Eina_Model_Type,
192       NULL, // no type as EINA_MODEL_TYPE_STRUCT is not constant initializer!
193       NULL, // no extra interfaces
194       NULL  // no extra events);
195       );
196    person_type.parent = EINA_MODEL_TYPE_STRUCT;
197    // Set our overloaded methods:
198    person_type.constructor = _person_constructor;
199
200    typedef struct _Address_Book Address_Book;
201    struct _Address_Book
202    {
203       const char *filename;
204    };
205    static Eina_Value_Struct_Member address_book_members[] = {
206      // no eina_value_type as they are not constant initializers, see below.
207      EINA_VALUE_STRUCT_MEMBER(NULL, Address_Book, filename)
208    };
209    address_book_members[0].type = EINA_VALUE_TYPE_STRING;
210    static Eina_Value_Struct_Desc address_book_desc = {
211      EINA_VALUE_STRUCT_DESC_VERSION,
212      NULL, // no special operations
213      address_book_members,
214      EINA_C_ARRAY_LENGTH(address_book_members),
215      sizeof(Address_Book)
216    };
217    static Eina_Model_Type address_book_type = EINA_MODEL_TYPE_INIT_NOPRIVATE
218      ("Address_Book_Type",
219       Eina_Model_Type,
220       NULL, // no type as EINA_MODEL_TYPE_STRUCT is not constant initializer!
221       NULL, // no extra interfaces
222       NULL  // no extra events);
223       );
224    address_book_type.parent = EINA_MODEL_TYPE_STRUCT;
225    // Set our overloaded methods:
226    address_book_type.constructor = _address_book_constructor;
227    address_book_type.load = _address_book_load;
228
229    // Expose the configured pointers to public usage:
230    // NOTE: they are static, so they live after this function returns!
231    PERSON_TYPE = &person_type;
232    PERSON_DESC = &person_desc;
233
234    ADDRESS_BOOK_TYPE = &address_book_type;
235    ADDRESS_BOOK_DESC = &address_book_desc;
236 }