diff options
Diffstat (limited to '')
-rw-r--r-- | libraries/eina/src/examples/eina_model_03.c | 236 |
1 files changed, 236 insertions, 0 deletions
diff --git a/libraries/eina/src/examples/eina_model_03.c b/libraries/eina/src/examples/eina_model_03.c new file mode 100644 index 0000000..a5e2562 --- /dev/null +++ b/libraries/eina/src/examples/eina_model_03.c | |||
@@ -0,0 +1,236 @@ | |||
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 | } | ||