2 * Copyright 2013 Samsung Electronics Co., Ltd
4 * Licensed under the Flora License, Version 1.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
8 * http://floralicense.org/license/
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.
19 #include <stdlib.h> /* malloc */
20 #include <string.h> /* strdup */
24 #include <livebox-errno.h>
28 #include "livebox_internal.h"
29 #include "desc_parser.h"
32 #include "critical_log.h"
34 #define TYPE_TEXT "text"
35 #define TYPE_IMAGE "image"
36 #define TYPE_EDJE "edje"
37 #define TYPE_SIGNAL "signal"
38 #define TYPE_INFO "info"
39 #define TYPE_DRAG "drag"
41 #define INFO_SIZE "size"
42 #define INFO_CATEGORY "category"
64 static int update_text(struct livebox *handle, struct block *block, int is_pd)
66 struct livebox_script_operators *ops;
68 if (!block || !block->part || !block->data) {
69 ErrPrint("Invalid argument\n");
70 return LB_STATUS_ERROR_INVALID;
73 ops = is_pd ? &handle->pd.data.ops : &handle->lb.data.ops;
75 ops->update_text(handle, (const char *)block->id, (const char *)block->part, (const char *)block->data);
80 static int update_image(struct livebox *handle, struct block *block, int is_pd)
82 struct livebox_script_operators *ops;
83 if (!block || !block->part) {
84 ErrPrint("Invalid argument\n");
85 return LB_STATUS_ERROR_INVALID;
88 ops = is_pd ? &handle->pd.data.ops : &handle->lb.data.ops;
89 if (ops->update_image)
90 ops->update_image(handle, block->id, block->part, block->data, block->option);
95 static int update_script(struct livebox *handle, struct block *block, int is_pd)
97 struct livebox_script_operators *ops;
98 if (!block || !block->part) {
99 ErrPrint("Invalid argument\n");
100 return LB_STATUS_ERROR_INVALID;
103 ops = is_pd ? &handle->pd.data.ops : &handle->lb.data.ops;
104 if (ops->update_script)
105 ops->update_script(handle, block->id, block->part, block->data, block->option);
110 static int update_signal(struct livebox *handle, struct block *block, int is_pd)
112 struct livebox_script_operators *ops;
115 ErrPrint("Invalid argument\n");
116 return LB_STATUS_ERROR_INVALID;
119 ops = is_pd ? &handle->pd.data.ops : &handle->lb.data.ops;
120 if (ops->update_signal)
121 ops->update_signal(handle, block->id, block->data, block->part);
126 static int update_drag(struct livebox *handle, struct block *block, int is_pd)
129 struct livebox_script_operators *ops;
131 if (!block || !block->data || !block->part) {
132 ErrPrint("Invalid argument\n");
133 return LB_STATUS_ERROR_INVALID;
136 ops = is_pd ? &handle->pd.data.ops : &handle->lb.data.ops;
138 if (sscanf(block->data, "%lfx%lf", &dx, &dy) != 2) {
139 ErrPrint("Invalid format of data\n");
140 return LB_STATUS_ERROR_INVALID;
143 if (ops->update_drag)
144 ops->update_drag(handle, block->id, block->part, dx, dy);
149 static int update_info(struct livebox *handle, struct block *block, int is_pd)
151 struct livebox_script_operators *ops;
153 if (!block || !block->part || !block->data) {
154 ErrPrint("Invalid argument\n");
155 return LB_STATUS_ERROR_INVALID;
158 ops = is_pd ? &handle->pd.data.ops : &handle->lb.data.ops;
160 if (!strcasecmp(block->part, INFO_SIZE)) {
163 if (sscanf(block->data, "%dx%d", &w, &h) != 2) {
164 ErrPrint("Invalid format (%s)\n", block->data);
165 return LB_STATUS_ERROR_INVALID;
168 if (ops->update_info_size)
169 ops->update_info_size(handle, block->id, w, h);
171 } else if (!strcasecmp(block->part, INFO_CATEGORY)) {
172 if (ops->update_info_category)
173 ops->update_info_category(handle, block->id, block->data);
179 static inline int update_begin(struct livebox *handle, int is_pd)
181 struct livebox_script_operators *ops;
183 ops = is_pd ? &handle->pd.data.ops : &handle->lb.data.ops;
185 if (ops->update_begin)
186 ops->update_begin(handle);
191 static inline int update_end(struct livebox *handle, int is_pd)
193 struct livebox_script_operators *ops;
195 ops = is_pd ? &handle->pd.data.ops : &handle->lb.data.ops;
198 ops->update_end(handle);
203 int parse_desc(struct livebox *handle, const char *descfile, int is_pd)
221 const char *field_name[] = {
231 register int field_idx;
232 register int idx = 0;
237 int (*handler)(struct livebox *handle, struct block *block, int is_pd);
241 .handler = update_text,
245 .handler = update_image,
249 .handler = update_script,
253 .handler = update_signal,
257 .handler = update_drag,
261 .handler = update_info,
269 fp = fopen(descfile, "rt");
271 ErrPrint("Error: %s\n", strerror(errno));
272 return LB_STATUS_ERROR_IO;
275 update_begin(handle, is_pd);
292 update_end(handle, is_pd);
294 return LB_STATUS_ERROR_INVALID;
305 block = calloc(1, sizeof(*block));
307 CRITICAL_LOG("Heap: %s\n", strerror(errno));
308 update_end(handle, is_pd);
310 return LB_STATUS_ERROR_MEMORY;
328 if (field_name[field_idx][idx] != '\0')
369 state = VALUE_OPTION;
372 block->option = NULL;
373 block->option_len = 0;
396 if (field_name[field_idx][idx] != ch) {
399 ungetc(field_name[field_idx][idx], fp);
402 if (field_name[field_idx] == NULL)
413 if (idx == block->type_len) {
414 block->type_len += 256;
415 block->type = realloc(block->type, block->type_len);
417 CRITICAL_LOG("Heap: %s\n", strerror(errno));
423 block->type[idx] = '\0';
430 block->type[idx] = ch;
435 if (idx == block->part_len) {
436 block->part_len += 256;
437 block->part = realloc(block->part, block->part_len);
439 CRITICAL_LOG("Heap: %s\n", strerror(errno));
445 block->part[idx] = '\0';
452 block->part[idx] = ch;
457 if (idx == block->data_len) {
458 block->data_len += 256;
459 block->data = realloc(block->data, block->data_len);
461 CRITICAL_LOG("Heap: %s\n", strerror(errno));
467 block->data[idx] = '\0';
474 block->data[idx] = ch;
479 if (idx == block->file_len) {
480 block->file_len += 256;
481 block->file = realloc(block->file, block->file_len);
483 CRITICAL_LOG("Heap: %s\n", strerror(errno));
489 block->file[idx] = '\0';
496 block->file[idx] = ch;
501 if (idx == block->option_len) {
502 block->option_len += 256;
503 block->option = realloc(block->option, block->option_len);
504 if (!block->option) {
505 CRITICAL_LOG("Heap: %s\n", strerror(errno));
511 block->option[idx] = '\0';
518 block->option[idx] = ch;
522 if (idx == block->id_len) {
523 block->id_len += 256;
524 block->id = realloc(block->id, block->id_len);
526 CRITICAL_LOG("Heap: %s\n", strerror(errno));
532 block->id[idx] = '\0';
544 block->file = strdup(util_uri_to_path(handle->id));
550 while (handlers[i].type) {
551 if (!strcasecmp(handlers[i].type, block->type)) {
552 handlers[i].handler(handle, block, is_pd);
558 if (!handlers[i].type)
559 ErrPrint("Unknown block type: %s\n", block->type);
578 if (state != UNKNOWN)
581 update_end(handle, is_pd);
587 ErrPrint("Parse error\n");
598 update_end(handle, is_pd);
601 return LB_STATUS_ERROR_INVALID;