Add:Core:Support for position_coord_geo parsing
[navit-package] / src / attr.c
1 #include <stdlib.h>
2 #include <string.h>
3 #include <stdio.h>
4 #include <glib.h>
5 #include "debug.h"
6 #include "item.h"
7 #include "coord.h"
8 #include "transform.h"
9 #include "color.h"
10 #include "attr.h"
11
12 struct attr_name {
13         enum attr_type attr;
14         char *name;
15 };
16
17
18 static struct attr_name attr_names[]={
19 #define ATTR2(x,y) ATTR(y)
20 #define ATTR(x) { attr_##x, #x },
21 #include "attr_def.h"
22 #undef ATTR2
23 #undef ATTR
24 };
25
26 enum attr_type
27 attr_from_name(const char *name)
28 {
29         int i;
30
31         for (i=0 ; i < sizeof(attr_names)/sizeof(struct attr_name) ; i++) {
32                 if (! strcmp(attr_names[i].name, name))
33                         return attr_names[i].attr;
34         }
35         return attr_none;
36 }
37
38 char *
39 attr_to_name(enum attr_type attr)
40 {
41         int i;
42
43         for (i=0 ; i < sizeof(attr_names)/sizeof(struct attr_name) ; i++) {
44                 if (attr_names[i].attr == attr)
45                         return attr_names[i].name;
46         }
47         return NULL; 
48 }
49
50 struct attr *
51 attr_new_from_text(const char *name, const char *value)
52 {
53         enum attr_type attr;
54         struct attr *ret;
55         struct coord_geo *g;
56         struct coord c;
57
58         ret=g_new0(struct attr, 1);
59         dbg(1,"enter name='%s' value='%s'\n", name, value);
60         attr=attr_from_name(name);
61         ret->type=attr;
62         switch (attr) {
63         case attr_item_type:
64                 ret->u.item_type=item_from_name(value);
65                 break;
66         case attr_position_coord_geo:
67                 g=g_new(struct coord_geo, 1);
68                 ret->u.coord_geo=g;
69                 coord_parse(value, projection_mg, &c);
70                 transform_to_geo(projection_mg, &c, g);
71                 break;
72         default:
73                 if (attr >= attr_type_string_begin && attr <= attr_type_string_end) {
74                         ret->u.str=(char *)value;
75                         break;
76                 }
77                 if (attr >= attr_type_int_begin && attr <= attr_type_int_end) {
78                         ret->u.num=atoi(value);
79                         break;
80                 }
81                 if (attr >= attr_type_color_begin && attr <= attr_type_color_end) {
82                         struct color *color=g_new0(struct color, 1);
83                         int r,g,b,a;
84                         ret->u.color=color;
85                         if(strlen(value)==7){
86                                 sscanf(value,"#%02x%02x%02x", &r, &g, &b);
87                                 color->r = (r << 8) | r;
88                                 color->g = (g << 8) | g;
89                                 color->b = (b << 8) | b;
90                                 color->a = (65535);
91                         } else if(strlen(value)==9){
92                                 sscanf(value,"#%02x%02x%02x%02x", &r, &g, &b, &a);
93                                 color->r = (r << 8) | r;
94                                 color->g = (g << 8) | g;
95                                 color->b = (b << 8) | b;
96                                 color->a = (a << 8) | a;
97                         } else {
98                                 dbg(0,"color %s has unknown format\n",value);
99                         }
100                         break;
101                 }
102                 dbg(1,"default\n");
103                 g_free(ret);
104                 ret=NULL;
105         }
106         return ret;
107 }
108
109 struct attr *
110 attr_search(struct attr **attrs, struct attr *last, enum attr_type attr)
111 {
112         dbg(1, "enter attrs=%p\n", attrs);
113         while (*attrs) {
114                 dbg(1,"*attrs=%p\n", *attrs);
115                 if ((*attrs)->type == attr) {
116                         return *attrs;
117                 }
118                 attrs++;
119         }
120         return NULL;
121 }
122
123 int
124 attr_data_size(struct attr *attr)
125 {
126         if (attr->type >= attr_type_string_begin && attr->type <= attr_type_string_end) {
127                 return strlen(attr->u.str)+1;
128         }
129         if (attr->type >= attr_type_int_begin && attr->type <= attr_type_int_end) {
130                 return sizeof(attr->u.num);
131         }
132         return 0;
133 }
134
135 void *
136 attr_data_get(struct attr *attr)
137 {
138         if (attr->type >= attr_type_string_begin && attr->type <= attr_type_string_end) {
139                 return attr->u.str;
140         }
141         if (attr->type >= attr_type_int_begin && attr->type <= attr_type_int_end) {
142                 return &attr->u.num;
143         }
144         return NULL;
145 }
146
147 void
148 attr_data_set(struct attr *attr, void *data)
149 {
150         if (attr->type >= attr_type_string_begin && attr->type <= attr_type_string_end) {
151                 attr->u.str=data;
152         }
153         if (attr->type >= attr_type_int_begin && attr->type <= attr_type_int_end) {
154                 attr->u.num=*((int *)data);
155         }
156 }
157
158 void
159 attr_free(struct attr *attr)
160 {
161         if (attr->type == attr_position_coord_geo)
162                 g_free(attr->u.coord_geo);
163         if (attr->type >= attr_type_color_begin && attr->type <= attr_type_color_end) 
164                 g_free(attr->u.color);
165         g_free(attr);
166 }