/[zanavi_public1]/navit/navit/attr.c
ZANavi

Contents of /navit/navit/attr.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 40 - (show annotations) (download)
Wed Mar 4 14:00:54 2015 UTC (9 years ago) by zoff99
File MIME type: text/plain
File size: 22076 byte(s)
new market version, lots of fixes
1 /**
2 * ZANavi, Zoff Android Navigation system.
3 * Copyright (C) 2011-2012 Zoff <zoff@zoff.cc>
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * version 2 as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the
16 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 */
19
20 /**
21 * Navit, a modular navigation system.
22 * Copyright (C) 2005-2008 Navit Team
23 *
24 * This program is free software; you can redistribute it and/or
25 * modify it under the terms of the GNU General Public License
26 * version 2 as published by the Free Software Foundation.
27 *
28 * This program is distributed in the hope that it will be useful,
29 * but WITHOUT ANY WARRANTY; without even the implied warranty of
30 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31 * GNU General Public License for more details.
32 *
33 * You should have received a copy of the GNU General Public License
34 * along with this program; if not, write to the
35 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
36 * Boston, MA 02110-1301, USA.
37 */
38
39 #include <stdlib.h>
40 #include <string.h>
41 #include <stdio.h>
42 #include <glib.h>
43 #include "debug.h"
44 #include "item.h"
45 #include "coord.h"
46 #include "transform.h"
47 #include "color.h"
48 #include "attr.h"
49 #include "map.h"
50 #include "config.h"
51 #include "endianess.h"
52 #include "util.h"
53 #include "types.h"
54
55 struct attr_name {
56 enum attr_type attr;
57 char *name;
58 };
59
60
61 static struct attr_name attr_names[]={
62 #define ATTR2(x,y) ATTR(y)
63 #define ATTR(x) { attr_##x, #x },
64 #include "attr_def.h"
65 #undef ATTR2
66 #undef ATTR
67 };
68
69 enum attr_type
70 attr_from_name(const char *name)
71 {
72 int i;
73
74 for (i=0 ; i < sizeof(attr_names)/sizeof(struct attr_name) ; i++) {
75 if (! strcmp(attr_names[i].name, name))
76 return attr_names[i].attr;
77 }
78 return attr_none;
79 }
80
81
82 static int attr_match(enum attr_type search, enum attr_type found);
83
84
85
86 char *
87 attr_to_name(enum attr_type attr)
88 {
89 int i;
90
91 for (i=0 ; i < sizeof(attr_names)/sizeof(struct attr_name) ; i++) {
92 if (attr_names[i].attr == attr)
93 return attr_names[i].name;
94 }
95 return NULL;
96 }
97
98 struct attr *
99 attr_new_from_text(const char *name, const char *value)
100 {
101 enum attr_type attr;
102 struct attr *ret;
103 struct coord_geo *g;
104 struct coord c;
105 char *pos,*type_str,*str,*tok;
106 int min,max,count;
107
108 ret=g_new0(struct attr, 1);
109 dbg(1,"enter name='%s' value='%s'\n", name, value);
110 attr=attr_from_name(name);
111 ret->type=attr;
112 switch (attr) {
113 case attr_item_type:
114 ret->u.item_type=item_from_name(value);
115 break;
116 case attr_item_types:
117 count=0;
118 type_str=g_strdup(value);
119 str=type_str;
120 while ((tok=strtok(str, ","))) {
121 ret->u.item_types=g_realloc(ret->u.item_types, (count+2)*sizeof(enum item_type));
122 ret->u.item_types[count++]=item_from_name(tok);
123 ret->u.item_types[count]=type_none;
124 str=NULL;
125 }
126 g_free(type_str);
127 break;
128 case attr_attr_types:
129 count=0;
130 type_str=g_strdup(value);
131 str=type_str;
132 while ((tok=strtok(str, ","))) {
133 ret->u.attr_types=g_realloc(ret->u.attr_types, (count+2)*sizeof(enum attr_type));
134 ret->u.attr_types[count++]=attr_from_name(tok);
135 ret->u.attr_types[count]=attr_none;
136 str=NULL;
137 }
138 g_free(type_str);
139 break;
140 case attr_dash:
141 count=0;
142 type_str=g_strdup(value);
143 str=type_str;
144 while ((tok=strtok(str, ","))) {
145 ret->u.dash=g_realloc(ret->u.dash, (count+2)*sizeof(int));
146 ret->u.dash[count++]=g_ascii_strtoull(tok,NULL,0);
147 ret->u.dash[count]=0;
148 str=NULL;
149 }
150 g_free(type_str);
151 break;
152 case attr_order:
153 case attr_sequence_range:
154 case attr_angle_range:
155 case attr_speed_range:
156 pos=strchr(value, '-');
157 min=0;
158 max=32767;
159 if (! pos) {
160 sscanf(value,"%d",&min);
161 max=min;
162 } else if (pos == value)
163 sscanf(value,"-%d",&max);
164 else
165 sscanf(value,"%d-%d",&min, &max);
166 ret->u.range.min=min;
167 ret->u.range.max=max;
168 break;
169 default:
170 if (attr >= attr_type_string_begin && attr <= attr_type_string_end) {
171 ret->u.str=g_strdup(value);
172 break;
173 }
174 if (attr >= attr_type_int_begin && attr <= attr_type_int_end) {
175 if (value[0] == '0' && value[1] == 'x')
176 ret->u.num=strtoul(value, NULL, 0);
177 else
178 ret->u.num=strtol(value, NULL, 0);
179
180 if ((attr >= attr_type_rel_abs_begin) && (attr < attr_type_boolean_begin)) {
181 /* Absolute values are from -0x40000000 - 0x40000000, with 0x0 being 0 (who would have thought that?)
182 Relative values are from 0x40000001 - 0x80000000, with 0x60000000 being 0 */
183 if (strchr(value, '%')) {
184 if ((ret->u.num > 0x20000000) || (ret->u.num < -0x1FFFFFFF)) {
185 dbg(0, "Relative possibly-relative attribute with invalid value %i\n", ret->u.num);
186 }
187
188 ret->u.num += 0x60000000;
189 } else {
190 if ((ret->u.num > 0x40000000) || (ret->u.num < -0x40000000)) {
191 dbg(0, "Non-relative possibly-relative attribute with invalid value %i\n", ret->u.num);
192 }
193 }
194 } else if (attr >= attr_type_boolean_begin) { // also check for yes and no
195 if (g_ascii_strcasecmp(value,"no") && g_ascii_strcasecmp(value,"0") && g_ascii_strcasecmp(value,"false"))
196 ret->u.num=1;
197 else
198 ret->u.num=0;
199 }
200 break;
201 }
202 if (attr >= attr_type_color_begin && attr <= attr_type_color_end) {
203 struct color *color=g_new0(struct color, 1);
204 int r,g,b,a;
205 ret->u.color=color;
206 if(strlen(value)==7){
207 sscanf(value,"#%02x%02x%02x", &r, &g, &b);
208 color->r = (r << 8) | r;
209 color->g = (g << 8) | g;
210 color->b = (b << 8) | b;
211 color->a = (65535);
212 } else if(strlen(value)==9){
213 sscanf(value,"#%02x%02x%02x%02x", &r, &g, &b, &a);
214 color->r = (r << 8) | r;
215 color->g = (g << 8) | g;
216 color->b = (b << 8) | b;
217 color->a = (a << 8) | a;
218 } else {
219 dbg(0,"color %s has unknown format\n",value);
220 }
221 break;
222 }
223 if (attr >= attr_type_coord_geo_begin && attr <= attr_type_coord_geo_end) {
224 g=g_new(struct coord_geo, 1);
225 ret->u.coord_geo=g;
226 coord_parse(value, projection_mg, &c);
227 transform_to_geo(projection_mg, &c, g);
228 break;
229 }
230 dbg(1,"default\n");
231 g_free(ret);
232 ret=NULL;
233 }
234 return ret;
235 }
236
237 char *
238 flags_to_text(int flags)
239 {
240 char *ret=g_strdup_printf("0x%x:",flags);
241 if (flags & NAVIT_AF_ONEWAY) ret=g_strconcat_printf(ret,"%sNAVIT_AF_ONEWAY",ret?"|":"");
242 if (flags & NAVIT_AF_ONEWAYREV) ret=g_strconcat_printf(ret,"%sNAVIT_AF_ONEWAYREV",ret?"|":"");
243 if (flags & NAVIT_AF_SEGMENTED) ret=g_strconcat_printf(ret,"%sNAVIT_AF_SEGMENTED",ret?"|":"");
244 if (flags & NAVIT_AF_ROUNDABOUT) ret=g_strconcat_printf(ret,"%sNAVIT_AF_ROUNDABOUT",ret?"|":"");
245 if (flags & NAVIT_AF_ONEWAY_BICYCLE_NO) ret=g_strconcat_printf(ret,"%sNAVIT_AF_ONEWAY_BICYCLE_NO",ret?"|":"");
246 if (flags & NAVIT_AF_ONEWAY_BICYCLE_YES) ret=g_strconcat_printf(ret,"%sNAVIT_AF_ONEWAY_BICYCLE_YES",ret?"|":"");
247 if (flags & NAVIT_AF_ROUNDABOUT_VALID) ret=g_strconcat_printf(ret,"%sNAVIT_AF_ROUNDABOUT_VALID",ret?"|":"");
248 if (flags & NAVIT_AF_ONEWAY_EXCEPTION) ret=g_strconcat_printf(ret,"%sNAVIT_AF_ONEWAY_EXCEPTION",ret?"|":"");
249 if (flags & NAVIT_AF_SPEED_LIMIT) ret=g_strconcat_printf(ret,"%sNAVIT_AF_SPEED_LIMIT",ret?"|":"");
250 // if (flags & NAVIT_AF_RESERVED1) ret=g_strconcat_printf(ret,"%sNAVIT_AF_RESERVED1",ret?"|":"");
251 if (flags & NAVIT_AF_SIZE_OR_WEIGHT_LIMIT) ret=g_strconcat_printf(ret,"%sNAVIT_AF_SIZE_OR_WEIGHT_LIMIT",ret?"|":"");
252 if (flags & NAVIT_AF_THROUGH_TRAFFIC_LIMIT) ret=g_strconcat_printf(ret,"%sNAVIT_AF_THROUGH_TRAFFIC_LIMIT",ret?"|":"");
253 if (flags & NAVIT_AF_TOLL) ret=g_strconcat_printf(ret,"%sNAVIT_AF_TOLL",ret?"|":"");
254 if (flags & NAVIT_AF_SEASONAL) ret=g_strconcat_printf(ret,"%sNAVIT_AF_SEASONAL",ret?"|":"");
255 if (flags & NAVIT_AF_UNPAVED) ret=g_strconcat_printf(ret,"%sNAVIT_AF_UNPAVED",ret?"|":"");
256 // if (flags & NAVIT_AF_FORD) ret=g_strconcat_printf(ret,"%sNAVIT_AF_FORD",ret?"|":"");
257 if (flags & NAVIT_AF_UNDERGROUND) ret=g_strconcat_printf(ret,"%sNAVIT_AF_UNDERGROUND",ret?"|":"");
258 if (flags & NAVIT_AF_BRIDGE) ret=g_strconcat_printf(ret,"%sNAVIT_AF_BRIDGE",ret?"|":"");
259 if (flags & NAVIT_AF_DANGEROUS_GOODS) ret=g_strconcat_printf(ret,"%sNAVIT_AF_DANGEROUS_GOODS",ret?"|":"");
260 if ((flags & NAVIT_AF_ALL) == NAVIT_AF_ALL)
261 return g_strconcat_printf(ret,"%sNAVIT_AF_ALL",ret?"|":"");
262 if ((flags & NAVIT_AF_ALL) == NAVIT_AF_MOTORIZED_FAST)
263 return g_strconcat_printf(ret,"%sNAVIT_AF_MOTORIZED_FAST",ret?"|":"");
264 if (flags & NAVIT_AF_EMERGENCY_VEHICLES) ret=g_strconcat_printf(ret,"%sNAVIT_AF_EMERGENCY_VEHICLES",ret?"|":"");
265 if (flags & NAVIT_AF_TRANSPORT_TRUCK) ret=g_strconcat_printf(ret,"%sNAVIT_AF_TRANSPORT_TRUCK",ret?"|":"");
266 if (flags & NAVIT_AF_DELIVERY_TRUCK) ret=g_strconcat_printf(ret,"%sNAVIT_AF_DELIVERY_TRUCK",ret?"|":"");
267 if (flags & NAVIT_AF_PUBLIC_BUS) ret=g_strconcat_printf(ret,"%sNAVIT_AF_PUBLIC_BUS",ret?"|":"");
268 if (flags & NAVIT_AF_TAXI) ret=g_strconcat_printf(ret,"%sNAVIT_AF_TAXI",ret?"|":"");
269 if (flags & NAVIT_AF_HIGH_OCCUPANCY_CAR) ret=g_strconcat_printf(ret,"%sNAVIT_AF_HIGH_OCCUPANCY_CAR",ret?"|":"");
270 if (flags & NAVIT_AF_CAR) ret=g_strconcat_printf(ret,"%sNAVIT_AF_CAR",ret?"|":"");
271 if (flags & NAVIT_AF_MOTORCYCLE) ret=g_strconcat_printf(ret,"%sNAVIT_AF_MOTORCYCLE",ret?"|":"");
272 if (flags & NAVIT_AF_MOPED) ret=g_strconcat_printf(ret,"%sNAVIT_AF_MOPED",ret?"|":"");
273 if (flags & NAVIT_AF_HORSE) ret=g_strconcat_printf(ret,"%sNAVIT_AF_HORSE",ret?"|":"");
274 if (flags & NAVIT_AF_BIKE) ret=g_strconcat_printf(ret,"%sNAVIT_AF_BIKE",ret?"|":"");
275 if (flags & NAVIT_AF_PEDESTRIAN) ret=g_strconcat_printf(ret,"%sNAVIT_AF_PEDESTRIAN",ret?"|":"");
276 return ret;
277 }
278
279 char *
280 attr_to_text(struct attr *attr, struct map *map, int pretty)
281 {
282 char *ret;
283 enum attr_type type=attr->type;
284
285 if (type >= attr_type_item_begin && type <= attr_type_item_end)
286 {
287 struct item *item=attr->u.item;
288 struct attr type, data;
289 if (! item)
290 return g_strdup("(nil)");
291
292 if (! item->map || !map_get_attr(item->map, attr_type, &type, NULL))
293 type.u.str="";
294
295 if (! item->map || !map_get_attr(item->map, attr_data, &data, NULL))
296 data.u.str="";
297
298 return g_strdup_printf("type=0x%x id=0x%x,0x%x map=%p (%s:%s)", item->type, item->id_hi, item->id_lo, item->map, type.u.str, data.u.str);
299 }
300 if (type >= attr_type_string_begin && type <= attr_type_string_end) {
301 if (map) {
302 char *mstr;
303 if (attr->u.str) {
304 mstr=map_convert_string(map, attr->u.str);
305 ret=g_strdup(mstr);
306 map_convert_free(mstr);
307 } else
308 ret=g_strdup("(null)");
309
310 } else
311 ret=g_strdup(attr->u.str);
312 return ret;
313 }
314 if (type == attr_flags || type == attr_through_traffic_flags)
315 return flags_to_text(attr->u.num);
316 if (type >= attr_type_int_begin && type <= attr_type_int_end)
317 return g_strdup_printf("%d", attr->u.num);
318 if (type >= attr_type_int64_begin && type <= attr_type_int64_end)
319 return g_strdup_printf(LONGLONG_FMT, *attr->u.num64);
320 if (type >= attr_type_double_begin && type <= attr_type_double_end)
321 return g_strdup_printf("%f", *attr->u.numd);
322 if (type >= attr_type_object_begin && type <= attr_type_object_end)
323 return g_strdup_printf("(object[%s])", attr_to_name(type));
324 if (type >= attr_type_color_begin && type <= attr_type_color_end) {
325 if (attr->u.color->a != 65535)
326 return g_strdup_printf("#%02x%02x%02x%02x", attr->u.color->r>>8,attr->u.color->g>>8,attr->u.color->b>>8, attr->u.color->a>>8);
327 else
328 return g_strdup_printf("#%02x%02x%02x", attr->u.color->r>>8,attr->u.color->g>>8,attr->u.color->b>>8);
329 }
330 if (type >= attr_type_coord_geo_begin && type <= attr_type_coord_geo_end)
331 return g_strdup_printf("%f %f",attr->u.coord_geo->lng,attr->u.coord_geo->lat);
332 if (type == attr_zipfile_ref_block) {
333 int *data=attr->u.data;
334 return g_strdup_printf("0x%x,0x%x,0x%x",data[0],data[1],data[2]);
335 }
336 if (type == attr_item_id) {
337 int *data=attr->u.data;
338 return g_strdup_printf("0x%x,0x%x",data[0],data[1]);
339 }
340 if (type >= attr_type_group_begin && type <= attr_type_group_end) {
341 int i=0;
342 char *ret=g_strdup("");
343 char *sep="";
344 while (attr->u.attrs[i].type) {
345 char *val=attr_to_text(&attr->u.attrs[i], map, pretty);
346 ret=g_strconcat_printf(ret,"%s%s=%s",sep,attr_to_name(attr->u.attrs[i].type),val);
347 g_free(val);
348 sep=" ";
349 i++;
350 }
351 return ret;
352 }
353 if (type >= attr_type_item_type_begin && type <= attr_type_item_type_end) {
354 return g_strdup_printf("0x%x[%s]",attr->u.num,item_to_name(attr->u.num));
355 }
356 return g_strdup_printf("(no text[%s])", attr_to_name(type));
357 }
358
359 struct attr *
360 attr_search(struct attr **attrs, struct attr *last, enum attr_type attr)
361 {
362 dbg(1, "enter attrs=%p\n", attrs);
363 while (*attrs) {
364 dbg(1,"*attrs=%p\n", *attrs);
365 if ((*attrs)->type == attr) {
366 return *attrs;
367 }
368 attrs++;
369 }
370 return NULL;
371 }
372
373 static int
374 attr_match(enum attr_type search, enum attr_type found)
375 {
376 switch (search) {
377 case attr_any:
378 return 1;
379 case attr_any_xml:
380 switch (found) {
381 case attr_callback:
382 return 0;
383 default:
384 return 1;
385 }
386 default:
387 return search == found;
388 }
389 }
390
391 int
392 attr_generic_get_attr(struct attr **attrs, struct attr **def_attrs, enum attr_type type, struct attr *attr, struct attr_iter *iter)
393 {
394 while (attrs && *attrs)
395 {
396 if (attr_match(type,(*attrs)->type))
397 {
398 *attr=**attrs;
399 if (!iter)
400 {
401 return 1;
402 }
403
404 if (*((void **)iter) < (void *)attrs)
405 {
406 *((void **)iter)=(void *)attrs;
407 return 1;
408 }
409 }
410 attrs++;
411 }
412
413 if (type == attr_any || type == attr_any_xml)
414 {
415 return 0;
416 }
417
418 while (def_attrs && *def_attrs)
419 {
420 if ((*def_attrs)->type == type)
421 {
422 *attr=**def_attrs;
423 return 1;
424 }
425 def_attrs++;
426 }
427 return 0;
428 }
429
430
431 struct attr **
432 attr_generic_set_attr(struct attr **attrs, struct attr *attr)
433 {
434 struct attr **curr=attrs;
435 int i,count=0;
436 while (curr && *curr) {
437 if ((*curr)->type == attr->type) {
438 attr_free(*curr);
439 *curr=attr_dup(attr);
440 return attrs;
441 }
442 curr++;
443 count++;
444 }
445 curr=g_new0(struct attr *, count+2);
446 for (i = 0 ; i < count ; i++)
447 curr[i]=attrs[i];
448 curr[count]=attr_dup(attr);
449 curr[count+1]=NULL;
450 g_free(attrs);
451 return curr;
452 }
453
454 struct attr **
455 attr_generic_add_attr(struct attr **attrs, struct attr *attr)
456 {
457 struct attr **curr=attrs;
458 int i,count=0;
459 while (curr && *curr) {
460 curr++;
461 count++;
462 }
463 curr=g_new0(struct attr *, count+2);
464 for (i = 0 ; i < count ; i++)
465 curr[i]=attrs[i];
466 curr[count]=attr_dup(attr);
467 curr[count+1]=NULL;
468 g_free(attrs);
469 return curr;
470 }
471
472 struct attr **
473 attr_generic_remove_attr(struct attr **attrs, struct attr *attr)
474 {
475 struct attr **curr=attrs;
476 int i,j,count=0,found=0;
477 while (curr && *curr) {
478 if ((*curr)->type == attr->type && (*curr)->u.data == attr->u.data)
479 found=1;
480 curr++;
481 count++;
482 }
483 if (!found)
484 return attrs;
485 curr=g_new0(struct attr *, count);
486 j=0;
487 for (i = 0 ; i < count ; i++) {
488 if (attrs[i]->type != attr->type || attrs[i]->u.data != attr->u.data)
489 curr[j++]=attrs[i];
490 else
491 attr_free(attrs[i]);
492 }
493 curr[j]=NULL;
494 g_free(attrs);
495 return curr;
496 }
497
498 enum attr_type
499 attr_type_begin(enum attr_type type)
500 {
501 if (type < attr_type_item_begin)
502 return attr_none;
503 if (type < attr_type_int_begin)
504 return attr_type_item_begin;
505 if (type < attr_type_string_begin)
506 return attr_type_int_begin;
507 if (type < attr_type_special_begin)
508 return attr_type_string_begin;
509 if (type < attr_type_double_begin)
510 return attr_type_special_begin;
511 if (type < attr_type_coord_geo_begin)
512 return attr_type_double_begin;
513 if (type < attr_type_color_begin)
514 return attr_type_coord_geo_begin;
515 if (type < attr_type_object_begin)
516 return attr_type_color_begin;
517 if (type < attr_type_coord_begin)
518 return attr_type_object_begin;
519 if (type < attr_type_pcoord_begin)
520 return attr_type_coord_begin;
521 if (type < attr_type_callback_begin)
522 return attr_type_pcoord_begin;
523 if (type < attr_type_int64_begin)
524 return attr_type_callback_begin;
525 if (type <= attr_type_int64_end)
526 return attr_type_int64_begin;
527 return attr_none;
528 }
529
530 int
531 attr_data_size(struct attr *attr)
532 {
533 if (attr->type >= attr_type_string_begin && attr->type <= attr_type_string_end)
534 return strlen(attr->u.str)+1;
535 if (attr->type >= attr_type_int_begin && attr->type <= attr_type_int_end)
536 return sizeof(attr->u.num);
537 if (attr->type >= attr_type_coord_geo_begin && attr->type <= attr_type_coord_geo_end)
538 return sizeof(*attr->u.coord_geo);
539 if (attr->type >= attr_type_color_begin && attr->type <= attr_type_color_end)
540 return sizeof(*attr->u.color);
541 if (attr->type >= attr_type_object_begin && attr->type <= attr_type_object_end)
542 return sizeof(void *);
543 if (attr->type >= attr_type_item_begin && attr->type <= attr_type_item_end)
544 return sizeof(struct item);
545 if (attr->type >= attr_type_int64_begin && attr->type <= attr_type_int64_end)
546 return sizeof(*attr->u.num64);
547 if (attr->type == attr_order)
548 return sizeof(attr->u.range);
549 if (attr->type >= attr_type_double_begin && attr->type <= attr_type_double_end)
550 return sizeof(*attr->u.numd);
551 if (attr->type == attr_item_types) {
552 int i=0;
553 while (attr->u.item_types[i++] != type_none);
554 return i*sizeof(enum item_type);
555 }
556 if (attr->type >= attr_type_item_type_begin && attr->type <= attr_type_item_type_end)
557 return sizeof(enum item_type);
558 if (attr->type == attr_attr_types) {
559 int i=0;
560 while (attr->u.attr_types[i++] != attr_none);
561 return i*sizeof(enum attr_type);
562 }
563 dbg(0,"size for %s unknown\n", attr_to_name(attr->type));
564 return 0;
565 }
566
567 void *
568 attr_data_get(struct attr *attr)
569 {
570 if ((attr->type >= attr_type_int_begin && attr->type <= attr_type_int_end) ||
571 (attr->type >= attr_type_item_type_begin && attr->type <= attr_type_item_type_end))
572 return &attr->u.num;
573 if (attr->type == attr_order)
574 return &attr->u.range;
575 return attr->u.data;
576 }
577
578 void
579 attr_data_set(struct attr *attr, void *data)
580 {
581 if ((attr->type >= attr_type_int_begin && attr->type <= attr_type_int_end) ||
582 (attr->type >= attr_type_item_type_begin && attr->type <= attr_type_item_type_end))
583 attr->u.num=*((int *)data);
584 else
585 attr->u.data=data;
586 }
587
588 void
589 attr_data_set_le(struct attr * attr, void * data)
590 {
591 if ((attr->type >= attr_type_int_begin && attr->type <= attr_type_int_end) ||
592 (attr->type >= attr_type_item_type_begin && attr->type <= attr_type_item_type_end))
593 attr->u.num=le32_to_cpu(*((int *)data));
594 else if (attr->type == attr_order) {
595 attr->u.num=le32_to_cpu(*((int *)data));
596 attr->u.range.min=le16_to_cpu(attr->u.range.min);
597 attr->u.range.max=le16_to_cpu(attr->u.range.max);
598 }
599 else
600 /* Fixme: Handle long long */
601 attr->u.data=data;
602
603 }
604
605 void
606 attr_free(struct attr *attr)
607 {
608 if (!attr)
609 return;
610 if (!(attr->type >= attr_type_int_begin && attr->type <= attr_type_int_end) &&
611 !(attr->type >= attr_type_object_begin && attr->type <= attr_type_object_end))
612 g_free(attr->u.data);
613 g_free(attr);
614 }
615
616 void
617 attr_dup_content(struct attr *src, struct attr *dst)
618 {
619 // dbg(0,"enter\n");
620 int size;
621 dst->type=src->type;
622 if (src->type >= attr_type_int_begin && src->type <= attr_type_int_end)
623 dst->u.num=src->u.num;
624 else if (src->type >= attr_type_object_begin && src->type <= attr_type_object_end)
625 dst->u.data=src->u.data;
626 else {
627 size=attr_data_size(src);
628 if (size) {
629 dst->u.data=g_malloc(size);
630 memcpy(dst->u.data, src->u.data, size);
631 }
632 }
633 // dbg(0,"leave\n");
634 }
635
636 struct attr *
637 attr_dup(struct attr *attr)
638 {
639 struct attr *ret=g_new0(struct attr, 1);
640 attr_dup_content(attr, ret);
641 return ret;
642 }
643
644 void
645 attr_list_free(struct attr **attrs)
646 {
647 int count=0;
648 while (attrs && attrs[count]) {
649 attr_free(attrs[count++]);
650 }
651 g_free(attrs);
652 }
653
654 struct attr **
655 attr_list_dup(struct attr **attrs)
656 {
657 struct attr **ret=attrs;
658 int i,count=0;
659
660 while (attrs[count])
661 {
662 count++;
663 }
664 ret=g_new0(struct attr *, count+1);
665 for (i = 0 ; i < count ; i++)
666 {
667 ret[i]=attr_dup(attrs[i]);
668 }
669 return ret;
670 }
671
672
673 int
674 attr_from_line(char *line, char *name, int *pos, char *val_ret, char *name_ret)
675 {
676 int len=0,quoted;
677 char *p,*e,*n;
678
679 // dbg(1,"get_tag %s from %s\n", name, line);
680 if (name)
681 len=strlen(name);
682 if (pos)
683 p=line+*pos;
684 else
685 p=line;
686 for(;;) {
687 while (*p == ' ') {
688 p++;
689 }
690 if (! *p)
691 return 0;
692 n=p;
693 e=strchr(p,'=');
694 if (! e)
695 return 0;
696 p=e+1;
697 quoted=0;
698 while (*p) {
699 if (*p == ' ' && !quoted)
700 break;
701 if (*p == '"')
702 quoted=1-quoted;
703 p++;
704 }
705 if (name == NULL || (e-n == len && !strncmp(n, name, len))) {
706 if (name_ret) {
707 len=e-n;
708 strncpy(name_ret, n, len);
709 name_ret[len]='\0';
710 }
711 e++;
712 len=p-e;
713 if (e[0] == '"') {
714 e++;
715 len-=2;
716 }
717 strncpy(val_ret, e, len);
718 val_ret[len]='\0';
719 if (pos)
720 *pos=p-line;
721 return 1;
722 }
723 }
724 return 0;
725 }
726
727 /**
728 * Check if an enumeration of attribute types contains a specific attribute.
729 *
730 * @param types Pointer to the attr_type enumeration to be searched
731 * @param type The attr_type to be searched for
732 *
733 * @return 1 if the attribute type was found, 0 if it was not found or if a null pointer was passed as types
734 */
735 int
736 attr_types_contains(enum attr_type *types, enum attr_type type)
737 {
738 while (types && *types != attr_none) {
739 if (*types == type)
740 return 1;
741 types++;
742 }
743 return 0;
744 }
745
746 /**
747 * Check if an enumeration of attribute types contains a specific attribute.
748 * It is different from attr_types_contains in that it returns a caller-defined value if the pointer to the enumeration is NULL.
749 *
750 * @param types Pointer to the attr_type enumeration to be searched
751 * @param type The attr_type to be searched for
752 * @param deflt The default value to return if types is NULL.
753 *
754 * @return 1 if the attribute type was found, 0 if it was not found, the value of the deflt argument if types is NULL.
755 */
756 int
757 attr_types_contains_default(enum attr_type *types, enum attr_type type, int deflt)
758 {
759 if (!types) {
760 return deflt;
761 }
762 return attr_types_contains(types, type);
763 }

   
Visit the ZANavi Wiki