2 * Copyright 2013 Samsung Electronics Co., Ltd
4 * Licensed under the Flora License, Version 1.1 (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"
40 #define TYPE_ACCESS "access"
41 #define TYPE_OPERATE_ACCESS "access,operation"
43 #define INFO_SIZE "size"
44 #define INFO_CATEGORY "category"
66 static int update_text(struct livebox *handle, struct block *block, int is_pd)
68 struct livebox_script_operators *ops;
70 if (!block || !block->part || !block->data) {
71 ErrPrint("Invalid argument\n");
72 return LB_STATUS_ERROR_INVALID;
75 ops = is_pd ? &handle->pd.data.ops : &handle->lb.data.ops;
76 if (ops->update_text) {
77 ops->update_text(handle, (const char *)block->id, (const char *)block->part, (const char *)block->data);
83 static int update_image(struct livebox *handle, struct block *block, int is_pd)
85 struct livebox_script_operators *ops;
86 if (!block || !block->part) {
87 ErrPrint("Invalid argument\n");
88 return LB_STATUS_ERROR_INVALID;
91 ops = is_pd ? &handle->pd.data.ops : &handle->lb.data.ops;
92 if (ops->update_image) {
93 ops->update_image(handle, block->id, block->part, block->data, block->option);
99 static int update_script(struct livebox *handle, struct block *block, int is_pd)
101 struct livebox_script_operators *ops;
102 if (!block || !block->part) {
103 ErrPrint("Invalid argument\n");
104 return LB_STATUS_ERROR_INVALID;
107 ops = is_pd ? &handle->pd.data.ops : &handle->lb.data.ops;
108 if (ops->update_script) {
109 ops->update_script(handle, block->id, block->part, block->data, block->option);
115 static int update_signal(struct livebox *handle, struct block *block, int is_pd)
117 struct livebox_script_operators *ops;
120 ErrPrint("Invalid argument\n");
121 return LB_STATUS_ERROR_INVALID;
124 ops = is_pd ? &handle->pd.data.ops : &handle->lb.data.ops;
125 if (ops->update_signal) {
126 ops->update_signal(handle, block->id, block->data, block->part);
132 static int update_drag(struct livebox *handle, struct block *block, int is_pd)
135 struct livebox_script_operators *ops;
137 if (!block || !block->data || !block->part) {
138 ErrPrint("Invalid argument\n");
139 return LB_STATUS_ERROR_INVALID;
142 ops = is_pd ? &handle->pd.data.ops : &handle->lb.data.ops;
144 if (sscanf(block->data, "%lfx%lf", &dx, &dy) != 2) {
145 ErrPrint("Invalid format of data\n");
146 return LB_STATUS_ERROR_INVALID;
149 if (ops->update_drag) {
150 ops->update_drag(handle, block->id, block->part, dx, dy);
156 static int update_info(struct livebox *handle, struct block *block, int is_pd)
158 struct livebox_script_operators *ops;
160 if (!block || !block->part || !block->data) {
161 ErrPrint("Invalid argument\n");
162 return LB_STATUS_ERROR_INVALID;
165 ops = is_pd ? &handle->pd.data.ops : &handle->lb.data.ops;
167 if (!strcasecmp(block->part, INFO_SIZE)) {
170 if (sscanf(block->data, "%dx%d", &w, &h) != 2) {
171 ErrPrint("Invalid format (%s)\n", block->data);
172 return LB_STATUS_ERROR_INVALID;
175 if (ops->update_info_size) {
176 ops->update_info_size(handle, block->id, w, h);
178 } else if (!strcasecmp(block->part, INFO_CATEGORY)) {
179 if (ops->update_info_category) {
180 ops->update_info_category(handle, block->id, block->data);
187 static int update_access(struct livebox *handle, struct block *block, int is_pd)
189 struct livebox_script_operators *ops;
192 ErrPrint("Invalid argument\n");
193 return LB_STATUS_ERROR_INVALID;
196 ops = is_pd ? &handle->pd.data.ops : &handle->lb.data.ops;
197 if (ops->update_access) {
198 ops->update_access(handle, block->id, block->part, block->data, block->option);
204 static int operate_access(struct livebox *handle, struct block *block, int is_pd)
206 struct livebox_script_operators *ops;
209 ErrPrint("Invalid argument\n");
210 return LB_STATUS_ERROR_INVALID;
213 ops = is_pd ? &handle->pd.data.ops : &handle->lb.data.ops;
214 if (ops->operate_access) {
215 ops->operate_access(handle, block->id, block->part, block->data, block->option);
221 static inline int update_begin(struct livebox *handle, int is_pd)
223 struct livebox_script_operators *ops;
225 ops = is_pd ? &handle->pd.data.ops : &handle->lb.data.ops;
227 if (ops->update_begin) {
228 ops->update_begin(handle);
234 static inline int update_end(struct livebox *handle, int is_pd)
236 struct livebox_script_operators *ops;
238 ops = is_pd ? &handle->pd.data.ops : &handle->lb.data.ops;
240 if (ops->update_end) {
241 ops->update_end(handle);
247 int parse_desc(struct livebox *handle, const char *descfile, int is_pd)
265 const char *field_name[] = {
275 register int field_idx;
276 register int idx = 0;
281 int (*handler)(struct livebox *handle, struct block *block, int is_pd);
285 .handler = update_text,
289 .handler = update_image,
293 .handler = update_script,
297 .handler = update_signal,
301 .handler = update_drag,
305 .handler = update_info,
309 .handler = update_access,
312 .type = TYPE_OPERATE_ACCESS,
313 .handler = operate_access,
321 fp = fopen(descfile, "rt");
323 ErrPrint("Error: %s\n", strerror(errno));
324 return LB_STATUS_ERROR_IO;
327 update_begin(handle, is_pd);
344 update_end(handle, is_pd);
345 if (fclose(fp) != 0) {
346 ErrPrint("fclose: %s\n", strerror(errno));
348 return LB_STATUS_ERROR_INVALID;
361 block = calloc(1, sizeof(*block));
363 CRITICAL_LOG("Heap: %s\n", strerror(errno));
364 update_end(handle, is_pd);
365 if (fclose(fp) != 0) {
366 ErrPrint("fclose: %s\n", strerror(errno));
368 return LB_STATUS_ERROR_MEMORY;
387 if (field_name[field_idx][idx] != '\0') {
429 state = VALUE_OPTION;
432 block->option = NULL;
433 block->option_len = 0;
457 if (field_name[field_idx][idx] != ch) {
458 if (ungetc(ch, fp) != ch) {
459 ErrPrint("ungetc: %s\n", strerror(errno));
463 if (ungetc(field_name[field_idx][idx], fp) != field_name[field_idx][idx]) {
464 ErrPrint("ungetc: %s\n", strerror(errno));
469 if (field_name[field_idx] == NULL) {
481 if (idx == block->type_len) {
482 block->type_len += 256;
483 block->type = realloc(block->type, block->type_len);
485 CRITICAL_LOG("Heap: %s\n", strerror(errno));
491 block->type[idx] = '\0';
498 block->type[idx] = ch;
503 if (idx == block->part_len) {
504 block->part_len += 256;
505 block->part = realloc(block->part, block->part_len);
507 CRITICAL_LOG("Heap: %s\n", strerror(errno));
513 block->part[idx] = '\0';
520 block->part[idx] = ch;
525 if (idx == block->data_len) {
526 block->data_len += 256;
527 block->data = realloc(block->data, block->data_len);
529 CRITICAL_LOG("Heap: %s\n", strerror(errno));
535 block->data[idx] = '\0';
542 block->data[idx] = ch;
547 if (idx == block->file_len) {
548 block->file_len += 256;
549 block->file = realloc(block->file, block->file_len);
551 CRITICAL_LOG("Heap: %s\n", strerror(errno));
557 block->file[idx] = '\0';
564 block->file[idx] = ch;
569 if (idx == block->option_len) {
570 block->option_len += 256;
571 block->option = realloc(block->option, block->option_len);
572 if (!block->option) {
573 CRITICAL_LOG("Heap: %s\n", strerror(errno));
579 block->option[idx] = '\0';
586 block->option[idx] = ch;
590 if (idx == block->id_len) {
591 block->id_len += 256;
592 block->id = realloc(block->id, block->id_len);
594 CRITICAL_LOG("Heap: %s\n", strerror(errno));
600 block->id[idx] = '\0';
612 block->file = strdup(util_uri_to_path(handle->id));
619 while (handlers[i].type) {
620 if (!strcasecmp(handlers[i].type, block->type)) {
621 handlers[i].handler(handle, block, is_pd);
627 if (!handlers[i].type) {
628 ErrPrint("Unknown block type: %s\n", block->type);
648 if (state != UNKNOWN) {
652 update_end(handle, is_pd);
654 if (fclose(fp) != 0) {
655 ErrPrint("fclose: %s\n", strerror(errno));
660 ErrPrint("Parse error\n");
671 update_end(handle, is_pd);
673 if (fclose(fp) != 0) {
674 ErrPrint("fclose: %s\n", strerror(errno));
676 return LB_STATUS_ERROR_INVALID;