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

Contents of /navit/navit/attr.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2 - (hide annotations) (download)
Fri Oct 28 21:19:04 2011 UTC (12 years, 5 months ago) by zoff99
File MIME type: text/plain
File size: 20531 byte(s)
import files
1 zoff99 2 /**
2     * Navit, a modular navigation system.
3     * Copyright (C) 2005-2008 Navit Team
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     #include <stdlib.h>
21     #include <string.h>
22     #include <stdio.h>
23     #include <glib.h>
24     #include "debug.h"
25     #include "item.h"
26     #include "coord.h"
27     #include "transform.h"
28     #include "color.h"
29     #include "attr.h"
30     #include "map.h"
31     #include "config.h"
32     #include "endianess.h"
33     #include "util.h"
34     #include "types.h"
35    
36     struct attr_name {
37     enum attr_type attr;
38     char *name;
39     };
40    
41    
42     static struct attr_name attr_names[]={
43     #define ATTR2(x,y) ATTR(y)
44     #define ATTR(x) { attr_##x, #x },
45     #include "attr_def.h"
46     #undef ATTR2
47     #undef ATTR
48     };
49    
50     enum attr_type
51     attr_from_name(const char *name)
52     {
53     int i;
54    
55     for (i=0 ; i < sizeof(attr_names)/sizeof(struct attr_name) ; i++) {
56     if (! strcmp(attr_names[i].name, name))
57     return attr_names[i].attr;
58     }
59     return attr_none;
60     }
61    
62    
63     static int attr_match(enum attr_type search, enum attr_type found);
64    
65    
66    
67     char *
68     attr_to_name(enum attr_type attr)
69     {
70     int i;
71    
72     for (i=0 ; i < sizeof(attr_names)/sizeof(struct attr_name) ; i++) {
73     if (attr_names[i].attr == attr)
74     return attr_names[i].name;
75     }
76     return NULL;
77     }
78    
79     struct attr *
80     attr_new_from_text(const char *name, const char *value)
81     {
82     enum attr_type attr;
83     struct attr *ret;
84     struct coord_geo *g;
85     struct coord c;
86     char *pos,*type_str,*str,*tok;
87     int min,max,count;
88    
89     ret=g_new0(struct attr, 1);
90     dbg(1,"enter name='%s' value='%s'\n", name, value);
91     attr=attr_from_name(name);
92     ret->type=attr;
93     switch (attr) {
94     case attr_item_type:
95     ret->u.item_type=item_from_name(value);
96     break;
97     case attr_item_types:
98     count=0;
99     type_str=g_strdup(value);
100     str=type_str;
101     while ((tok=strtok(str, ","))) {
102     ret->u.item_types=g_realloc(ret->u.item_types, (count+2)*sizeof(enum item_type));
103     ret->u.item_types[count++]=item_from_name(tok);
104     ret->u.item_types[count]=type_none;
105     str=NULL;
106     }
107     g_free(type_str);
108     break;
109     case attr_attr_types:
110     count=0;
111     type_str=g_strdup(value);
112     str=type_str;
113     while ((tok=strtok(str, ","))) {
114     ret->u.attr_types=g_realloc(ret->u.attr_types, (count+2)*sizeof(enum attr_type));
115     ret->u.attr_types[count++]=attr_from_name(tok);
116     ret->u.attr_types[count]=attr_none;
117     str=NULL;
118     }
119     g_free(type_str);
120     break;
121     case attr_dash:
122     count=0;
123     type_str=g_strdup(value);
124     str=type_str;
125     while ((tok=strtok(str, ","))) {
126     ret->u.dash=g_realloc(ret->u.dash, (count+2)*sizeof(int));
127     ret->u.dash[count++]=g_ascii_strtoull(tok,NULL,0);
128     ret->u.dash[count]=0;
129     str=NULL;
130     }
131     g_free(type_str);
132     break;
133     case attr_order:
134     case attr_sequence_range:
135     case attr_angle_range:
136     case attr_speed_range:
137     pos=strchr(value, '-');
138     min=0;
139     max=32767;
140     if (! pos) {
141     sscanf(value,"%d",&min);
142     max=min;
143     } else if (pos == value)
144     sscanf(value,"-%d",&max);
145     else
146     sscanf(value,"%d-%d",&min, &max);
147     ret->u.range.min=min;
148     ret->u.range.max=max;
149     break;
150     default:
151     if (attr >= attr_type_string_begin && attr <= attr_type_string_end) {
152     ret->u.str=g_strdup(value);
153     break;
154     }
155     if (attr >= attr_type_int_begin && attr <= attr_type_int_end) {
156     if (value[0] == '0' && value[1] == 'x')
157     ret->u.num=strtoul(value, NULL, 0);
158     else
159     ret->u.num=strtol(value, NULL, 0);
160    
161     if ((attr >= attr_type_rel_abs_begin) && (attr < attr_type_boolean_begin)) {
162     /* Absolute values are from -0x40000000 - 0x40000000, with 0x0 being 0 (who would have thought that?)
163     Relative values are from 0x40000001 - 0x80000000, with 0x60000000 being 0 */
164     if (strchr(value, '%')) {
165     if ((ret->u.num > 0x20000000) || (ret->u.num < -0x1FFFFFFF)) {
166     dbg(0, "Relative possibly-relative attribute with invalid value %i\n", ret->u.num);
167     }
168    
169     ret->u.num += 0x60000000;
170     } else {
171     if ((ret->u.num > 0x40000000) || (ret->u.num < -0x40000000)) {
172     dbg(0, "Non-relative possibly-relative attribute with invalid value %i\n", ret->u.num);
173     }
174     }
175     } else if (attr >= attr_type_boolean_begin) { // also check for yes and no
176     if (g_ascii_strcasecmp(value,"no") && g_ascii_strcasecmp(value,"0") && g_ascii_strcasecmp(value,"false"))
177     ret->u.num=1;
178     else
179     ret->u.num=0;
180     }
181     break;
182     }
183     if (attr >= attr_type_color_begin && attr <= attr_type_color_end) {
184     struct color *color=g_new0(struct color, 1);
185     int r,g,b,a;
186     ret->u.color=color;
187     if(strlen(value)==7){
188     sscanf(value,"#%02x%02x%02x", &r, &g, &b);
189     color->r = (r << 8) | r;
190     color->g = (g << 8) | g;
191     color->b = (b << 8) | b;
192     color->a = (65535);
193     } else if(strlen(value)==9){
194     sscanf(value,"#%02x%02x%02x%02x", &r, &g, &b, &a);
195     color->r = (r << 8) | r;
196     color->g = (g << 8) | g;
197     color->b = (b << 8) | b;
198     color->a = (a << 8) | a;
199     } else {
200     dbg(0,"color %s has unknown format\n",value);
201     }
202     break;
203     }
204     if (attr >= attr_type_coord_geo_begin && attr <= attr_type_coord_geo_end) {
205     g=g_new(struct coord_geo, 1);
206     ret->u.coord_geo=g;
207     coord_parse(value, projection_mg, &c);
208     transform_to_geo(projection_mg, &c, g);
209     break;
210     }
211     dbg(1,"default\n");
212     g_free(ret);
213     ret=NULL;
214     }
215     return ret;
216     }
217    
218     char *
219     flags_to_text(int flags)
220     {
221     char *ret=g_strdup_printf("0x%x:",flags);
222     if (flags & AF_ONEWAY) ret=g_strconcat_printf(ret,"%sAF_ONEWAY",ret?"|":"");
223     if (flags & AF_ONEWAYREV) ret=g_strconcat_printf(ret,"%sAF_ONEWAYREV",ret?"|":"");
224     if (flags & AF_SEGMENTED) ret=g_strconcat_printf(ret,"%sAF_SEGMENTED",ret?"|":"");
225     if (flags & AF_ROUNDABOUT) ret=g_strconcat_printf(ret,"%sAF_ROUNDABOUT",ret?"|":"");
226     if (flags & AF_ROUNDABOUT_VALID) ret=g_strconcat_printf(ret,"%sAF_ROUNDABOUT_VALID",ret?"|":"");
227     if (flags & AF_ONEWAY_EXCEPTION) ret=g_strconcat_printf(ret,"%sAF_ONEWAY_EXCEPTION",ret?"|":"");
228     if (flags & AF_SPEED_LIMIT) ret=g_strconcat_printf(ret,"%sAF_SPEED_LIMIT",ret?"|":"");
229     if (flags & AF_RESERVED1) ret=g_strconcat_printf(ret,"%sAF_RESERVED1",ret?"|":"");
230     if (flags & AF_SIZE_OR_WEIGHT_LIMIT) ret=g_strconcat_printf(ret,"%sAF_SIZE_OR_WEIGHT_LIMIT",ret?"|":"");
231     if (flags & AF_THROUGH_TRAFFIC_LIMIT) ret=g_strconcat_printf(ret,"%sAF_THROUGH_TRAFFIC_LIMIT",ret?"|":"");
232     if (flags & AF_TOLL) ret=g_strconcat_printf(ret,"%sAF_TOLL",ret?"|":"");
233     if (flags & AF_SEASONAL) ret=g_strconcat_printf(ret,"%sAF_SEASONAL",ret?"|":"");
234     if (flags & AF_UNPAVED) ret=g_strconcat_printf(ret,"%sAF_UNPAVED",ret?"|":"");
235     if (flags & AF_FORD) ret=g_strconcat_printf(ret,"%sAF_FORD",ret?"|":"");
236     if (flags & AF_UNDERGROUND) ret=g_strconcat_printf(ret,"%sAF_UNDERGROUND",ret?"|":"");
237     if (flags & AF_DANGEROUS_GOODS) ret=g_strconcat_printf(ret,"%sAF_DANGEROUS_GOODS",ret?"|":"");
238     if ((flags & AF_ALL) == AF_ALL)
239     return g_strconcat_printf(ret,"%sAF_ALL",ret?"|":"");
240     if ((flags & AF_ALL) == AF_MOTORIZED_FAST)
241     return g_strconcat_printf(ret,"%sAF_MOTORIZED_FAST",ret?"|":"");
242     if (flags & AF_EMERGENCY_VEHICLES) ret=g_strconcat_printf(ret,"%sAF_EMERGENCY_VEHICLES",ret?"|":"");
243     if (flags & AF_TRANSPORT_TRUCK) ret=g_strconcat_printf(ret,"%sAF_TRANSPORT_TRUCK",ret?"|":"");
244     if (flags & AF_DELIVERY_TRUCK) ret=g_strconcat_printf(ret,"%sAF_DELIVERY_TRUCK",ret?"|":"");
245     if (flags & AF_PUBLIC_BUS) ret=g_strconcat_printf(ret,"%sAF_PUBLIC_BUS",ret?"|":"");
246     if (flags & AF_TAXI) ret=g_strconcat_printf(ret,"%sAF_TAXI",ret?"|":"");
247     if (flags & AF_HIGH_OCCUPANCY_CAR) ret=g_strconcat_printf(ret,"%sAF_HIGH_OCCUPANCY_CAR",ret?"|":"");
248     if (flags & AF_CAR) ret=g_strconcat_printf(ret,"%sAF_CAR",ret?"|":"");
249     if (flags & AF_MOTORCYCLE) ret=g_strconcat_printf(ret,"%sAF_MOTORCYCLE",ret?"|":"");
250     if (flags & AF_MOPED) ret=g_strconcat_printf(ret,"%sAF_MOPED",ret?"|":"");
251     if (flags & AF_HORSE) ret=g_strconcat_printf(ret,"%sAF_HORSE",ret?"|":"");
252     if (flags & AF_BIKE) ret=g_strconcat_printf(ret,"%sAF_BIKE",ret?"|":"");
253     if (flags & AF_PEDESTRIAN) ret=g_strconcat_printf(ret,"%sAF_PEDESTRIAN",ret?"|":"");
254     return ret;
255     }
256    
257     char *
258     attr_to_text(struct attr *attr, struct map *map, int pretty)
259     {
260     char *ret;
261     enum attr_type type=attr->type;
262    
263     if (type >= attr_type_item_begin && type <= attr_type_item_end) {
264     struct item *item=attr->u.item;
265     struct attr type, data;
266     if (! item)
267     return g_strdup("(nil)");
268     if (! item->map || !map_get_attr(item->map, attr_type, &type, NULL))
269     type.u.str="";
270     if (! item->map || !map_get_attr(item->map, attr_data, &data, NULL))
271     data.u.str="";
272     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);
273     }
274     if (type >= attr_type_string_begin && type <= attr_type_string_end) {
275     if (map) {
276     char *mstr;
277     if (attr->u.str) {
278     mstr=map_convert_string(map, attr->u.str);
279     ret=g_strdup(mstr);
280     map_convert_free(mstr);
281     } else
282     ret=g_strdup("(null)");
283    
284     } else
285     ret=g_strdup(attr->u.str);
286     return ret;
287     }
288     if (type == attr_flags || type == attr_through_traffic_flags)
289     return flags_to_text(attr->u.num);
290     if (type >= attr_type_int_begin && type <= attr_type_int_end)
291     return g_strdup_printf("%d", attr->u.num);
292     if (type >= attr_type_int64_begin && type <= attr_type_int64_end)
293     return g_strdup_printf(LONGLONG_FMT, *attr->u.num64);
294     if (type >= attr_type_double_begin && type <= attr_type_double_end)
295     return g_strdup_printf("%f", *attr->u.numd);
296     if (type >= attr_type_object_begin && type <= attr_type_object_end)
297     return g_strdup_printf("(object[%s])", attr_to_name(type));
298     if (type >= attr_type_color_begin && type <= attr_type_color_end) {
299     if (attr->u.color->a != 65535)
300     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);
301     else
302     return g_strdup_printf("#%02x%02x%02x", attr->u.color->r>>8,attr->u.color->g>>8,attr->u.color->b>>8);
303     }
304     if (type >= attr_type_coord_geo_begin && type <= attr_type_coord_geo_end)
305     return g_strdup_printf("%f %f",attr->u.coord_geo->lng,attr->u.coord_geo->lat);
306     if (type == attr_zipfile_ref_block) {
307     int *data=attr->u.data;
308     return g_strdup_printf("0x%x,0x%x,0x%x",data[0],data[1],data[2]);
309     }
310     if (type == attr_item_id) {
311     int *data=attr->u.data;
312     return g_strdup_printf("0x%x,0x%x",data[0],data[1]);
313     }
314     if (type >= attr_type_group_begin && type <= attr_type_group_end) {
315     int i=0;
316     char *ret=g_strdup("");
317     char *sep="";
318     while (attr->u.attrs[i].type) {
319     char *val=attr_to_text(&attr->u.attrs[i], map, pretty);
320     ret=g_strconcat_printf(ret,"%s%s=%s",sep,attr_to_name(attr->u.attrs[i].type),val);
321     g_free(val);
322     sep=" ";
323     i++;
324     }
325     return ret;
326     }
327     if (type >= attr_type_item_type_begin && type <= attr_type_item_type_end) {
328     return g_strdup_printf("0x%x[%s]",attr->u.num,item_to_name(attr->u.num));
329     }
330     return g_strdup_printf("(no text[%s])", attr_to_name(type));
331     }
332    
333     struct attr *
334     attr_search(struct attr **attrs, struct attr *last, enum attr_type attr)
335     {
336     dbg(1, "enter attrs=%p\n", attrs);
337     while (*attrs) {
338     dbg(1,"*attrs=%p\n", *attrs);
339     if ((*attrs)->type == attr) {
340     return *attrs;
341     }
342     attrs++;
343     }
344     return NULL;
345     }
346    
347     static int
348     attr_match(enum attr_type search, enum attr_type found)
349     {
350     switch (search) {
351     case attr_any:
352     return 1;
353     case attr_any_xml:
354     switch (found) {
355     case attr_callback:
356     return 0;
357     default:
358     return 1;
359     }
360     default:
361     return search == found;
362     }
363     }
364    
365     int
366     attr_generic_get_attr(struct attr **attrs, struct attr **def_attrs, enum attr_type type, struct attr *attr, struct attr_iter *iter)
367     {
368     while (attrs && *attrs) {
369     if (attr_match(type,(*attrs)->type)) {
370     *attr=**attrs;
371     if (!iter)
372     return 1;
373     if (*((void **)iter) < (void *)attrs) {
374     *((void **)iter)=(void *)attrs;
375     return 1;
376     }
377     }
378     attrs++;
379     }
380     if (type == attr_any || type == attr_any_xml)
381     return 0;
382     while (def_attrs && *def_attrs) {
383     if ((*def_attrs)->type == type) {
384     *attr=**def_attrs;
385     return 1;
386     }
387     def_attrs++;
388     }
389     return 0;
390     }
391    
392     struct attr **
393     attr_generic_set_attr(struct attr **attrs, struct attr *attr)
394     {
395     struct attr **curr=attrs;
396     int i,count=0;
397     while (curr && *curr) {
398     if ((*curr)->type == attr->type) {
399     attr_free(*curr);
400     *curr=attr_dup(attr);
401     return attrs;
402     }
403     curr++;
404     count++;
405     }
406     curr=g_new0(struct attr *, count+2);
407     for (i = 0 ; i < count ; i++)
408     curr[i]=attrs[i];
409     curr[count]=attr_dup(attr);
410     curr[count+1]=NULL;
411     g_free(attrs);
412     return curr;
413     }
414    
415     struct attr **
416     attr_generic_add_attr(struct attr **attrs, struct attr *attr)
417     {
418     struct attr **curr=attrs;
419     int i,count=0;
420     while (curr && *curr) {
421     curr++;
422     count++;
423     }
424     curr=g_new0(struct attr *, count+2);
425     for (i = 0 ; i < count ; i++)
426     curr[i]=attrs[i];
427     curr[count]=attr_dup(attr);
428     curr[count+1]=NULL;
429     g_free(attrs);
430     return curr;
431     }
432    
433     struct attr **
434     attr_generic_remove_attr(struct attr **attrs, struct attr *attr)
435     {
436     struct attr **curr=attrs;
437     int i,j,count=0,found=0;
438     while (curr && *curr) {
439     if ((*curr)->type == attr->type && (*curr)->u.data == attr->u.data)
440     found=1;
441     curr++;
442     count++;
443     }
444     if (!found)
445     return attrs;
446     curr=g_new0(struct attr *, count);
447     j=0;
448     for (i = 0 ; i < count ; i++) {
449     if (attrs[i]->type != attr->type || attrs[i]->u.data != attr->u.data)
450     curr[j++]=attrs[i];
451     else
452     attr_free(attrs[i]);
453     }
454     curr[j]=NULL;
455     g_free(attrs);
456     return curr;
457     }
458    
459     enum attr_type
460     attr_type_begin(enum attr_type type)
461     {
462     if (type < attr_type_item_begin)
463     return attr_none;
464     if (type < attr_type_int_begin)
465     return attr_type_item_begin;
466     if (type < attr_type_string_begin)
467     return attr_type_int_begin;
468     if (type < attr_type_special_begin)
469     return attr_type_string_begin;
470     if (type < attr_type_double_begin)
471     return attr_type_special_begin;
472     if (type < attr_type_coord_geo_begin)
473     return attr_type_double_begin;
474     if (type < attr_type_color_begin)
475     return attr_type_coord_geo_begin;
476     if (type < attr_type_object_begin)
477     return attr_type_color_begin;
478     if (type < attr_type_coord_begin)
479     return attr_type_object_begin;
480     if (type < attr_type_pcoord_begin)
481     return attr_type_coord_begin;
482     if (type < attr_type_callback_begin)
483     return attr_type_pcoord_begin;
484     if (type < attr_type_int64_begin)
485     return attr_type_callback_begin;
486     if (type <= attr_type_int64_end)
487     return attr_type_int64_begin;
488     return attr_none;
489     }
490    
491     int
492     attr_data_size(struct attr *attr)
493     {
494     if (attr->type >= attr_type_string_begin && attr->type <= attr_type_string_end)
495     return strlen(attr->u.str)+1;
496     if (attr->type >= attr_type_int_begin && attr->type <= attr_type_int_end)
497     return sizeof(attr->u.num);
498     if (attr->type >= attr_type_coord_geo_begin && attr->type <= attr_type_coord_geo_end)
499     return sizeof(*attr->u.coord_geo);
500     if (attr->type >= attr_type_color_begin && attr->type <= attr_type_color_end)
501     return sizeof(*attr->u.color);
502     if (attr->type >= attr_type_object_begin && attr->type <= attr_type_object_end)
503     return sizeof(void *);
504     if (attr->type >= attr_type_item_begin && attr->type <= attr_type_item_end)
505     return sizeof(struct item);
506     if (attr->type >= attr_type_int64_begin && attr->type <= attr_type_int64_end)
507     return sizeof(*attr->u.num64);
508     if (attr->type == attr_order)
509     return sizeof(attr->u.range);
510     if (attr->type >= attr_type_double_begin && attr->type <= attr_type_double_end)
511     return sizeof(*attr->u.numd);
512     if (attr->type == attr_item_types) {
513     int i=0;
514     while (attr->u.item_types[i++] != type_none);
515     return i*sizeof(enum item_type);
516     }
517     if (attr->type >= attr_type_item_type_begin && attr->type <= attr_type_item_type_end)
518     return sizeof(enum item_type);
519     if (attr->type == attr_attr_types) {
520     int i=0;
521     while (attr->u.attr_types[i++] != attr_none);
522     return i*sizeof(enum attr_type);
523     }
524     dbg(0,"size for %s unknown\n", attr_to_name(attr->type));
525     return 0;
526     }
527    
528     void *
529     attr_data_get(struct attr *attr)
530     {
531     if ((attr->type >= attr_type_int_begin && attr->type <= attr_type_int_end) ||
532     (attr->type >= attr_type_item_type_begin && attr->type <= attr_type_item_type_end))
533     return &attr->u.num;
534     if (attr->type == attr_order)
535     return &attr->u.range;
536     return attr->u.data;
537     }
538    
539     void
540     attr_data_set(struct attr *attr, void *data)
541     {
542     if ((attr->type >= attr_type_int_begin && attr->type <= attr_type_int_end) ||
543     (attr->type >= attr_type_item_type_begin && attr->type <= attr_type_item_type_end))
544     attr->u.num=*((int *)data);
545     else
546     attr->u.data=data;
547     }
548    
549     void
550     attr_data_set_le(struct attr * attr, void * data)
551     {
552     if ((attr->type >= attr_type_int_begin && attr->type <= attr_type_int_end) ||
553     (attr->type >= attr_type_item_type_begin && attr->type <= attr_type_item_type_end))
554     attr->u.num=le32_to_cpu(*((int *)data));
555     else if (attr->type == attr_order) {
556     attr->u.num=le32_to_cpu(*((int *)data));
557     attr->u.range.min=le16_to_cpu(attr->u.range.min);
558     attr->u.range.max=le16_to_cpu(attr->u.range.max);
559     }
560     else
561     /* Fixme: Handle long long */
562     attr->u.data=data;
563    
564     }
565    
566     void
567     attr_free(struct attr *attr)
568     {
569     if (!attr)
570     return;
571     if (!(attr->type >= attr_type_int_begin && attr->type <= attr_type_int_end) &&
572     !(attr->type >= attr_type_object_begin && attr->type <= attr_type_object_end))
573     g_free(attr->u.data);
574     g_free(attr);
575     }
576    
577     void
578     attr_dup_content(struct attr *src, struct attr *dst)
579     {
580     int size;
581     dst->type=src->type;
582     if (src->type >= attr_type_int_begin && src->type <= attr_type_int_end)
583     dst->u.num=src->u.num;
584     else if (src->type >= attr_type_object_begin && src->type <= attr_type_object_end)
585     dst->u.data=src->u.data;
586     else {
587     size=attr_data_size(src);
588     if (size) {
589     dst->u.data=g_malloc(size);
590     memcpy(dst->u.data, src->u.data, size);
591     }
592     }
593     }
594    
595     struct attr *
596     attr_dup(struct attr *attr)
597     {
598     struct attr *ret=g_new0(struct attr, 1);
599     attr_dup_content(attr, ret);
600     return ret;
601     }
602    
603     void
604     attr_list_free(struct attr **attrs)
605     {
606     int count=0;
607     while (attrs && attrs[count]) {
608     attr_free(attrs[count++]);
609     }
610     g_free(attrs);
611     }
612    
613     struct attr **
614     attr_list_dup(struct attr **attrs)
615     {
616     struct attr **ret=attrs;
617     int i,count=0;
618    
619     while (attrs[count])
620     count++;
621     ret=g_new0(struct attr *, count+1);
622     for (i = 0 ; i < count ; i++)
623     ret[i]=attr_dup(attrs[i]);
624     return ret;
625     }
626    
627    
628     int
629     attr_from_line(char *line, char *name, int *pos, char *val_ret, char *name_ret)
630     {
631     int len=0,quoted;
632     char *p,*e,*n;
633    
634     dbg(1,"get_tag %s from %s\n", name, line);
635     if (name)
636     len=strlen(name);
637     if (pos)
638     p=line+*pos;
639     else
640     p=line;
641     for(;;) {
642     while (*p == ' ') {
643     p++;
644     }
645     if (! *p)
646     return 0;
647     n=p;
648     e=strchr(p,'=');
649     if (! e)
650     return 0;
651     p=e+1;
652     quoted=0;
653     while (*p) {
654     if (*p == ' ' && !quoted)
655     break;
656     if (*p == '"')
657     quoted=1-quoted;
658     p++;
659     }
660     if (name == NULL || (e-n == len && !strncmp(n, name, len))) {
661     if (name_ret) {
662     len=e-n;
663     strncpy(name_ret, n, len);
664     name_ret[len]='\0';
665     }
666     e++;
667     len=p-e;
668     if (e[0] == '"') {
669     e++;
670     len-=2;
671     }
672     strncpy(val_ret, e, len);
673     val_ret[len]='\0';
674     if (pos)
675     *pos=p-line;
676     return 1;
677     }
678     }
679     return 0;
680     }
681    
682     /**
683     * Check if an enumeration of attribute types contains a specific attribute.
684     *
685     * @param types Pointer to the attr_type enumeration to be searched
686     * @param type The attr_type to be searched for
687     *
688     * @return 1 if the attribute type was found, 0 if it was not found or if a null pointer was passed as types
689     */
690     int
691     attr_types_contains(enum attr_type *types, enum attr_type type)
692     {
693     while (types && *types != attr_none) {
694     if (*types == type)
695     return 1;
696     types++;
697     }
698     return 0;
699     }
700    
701     /**
702     * Check if an enumeration of attribute types contains a specific attribute.
703     * It is different from attr_types_contains in that it returns a caller-defined value if the pointer to the enumeration is NULL.
704     *
705     * @param types Pointer to the attr_type enumeration to be searched
706     * @param type The attr_type to be searched for
707     * @param deflt The default value to return if types is NULL.
708     *
709     * @return 1 if the attribute type was found, 0 if it was not found, the value of the deflt argument if types is NULL.
710     */
711     int
712     attr_types_contains_default(enum attr_type *types, enum attr_type type, int deflt)
713     {
714     if (!types) {
715     return deflt;
716     }
717     return attr_types_contains(types, type);
718     }

   
Visit the ZANavi Wiki