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

Contents of /navit/navit/attr.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 28 - (hide annotations) (download)
Sun Jun 17 08:12:47 2012 UTC (11 years, 10 months ago) by zoff99
File MIME type: text/plain
File size: 21427 byte(s)
lots of new stuff and fixes
1 zoff99 2 /**
2 zoff99 27 * 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 zoff99 2 * 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 & AF_ONEWAY) ret=g_strconcat_printf(ret,"%sAF_ONEWAY",ret?"|":"");
242     if (flags & AF_ONEWAYREV) ret=g_strconcat_printf(ret,"%sAF_ONEWAYREV",ret?"|":"");
243     if (flags & AF_SEGMENTED) ret=g_strconcat_printf(ret,"%sAF_SEGMENTED",ret?"|":"");
244     if (flags & AF_ROUNDABOUT) ret=g_strconcat_printf(ret,"%sAF_ROUNDABOUT",ret?"|":"");
245     if (flags & AF_ROUNDABOUT_VALID) ret=g_strconcat_printf(ret,"%sAF_ROUNDABOUT_VALID",ret?"|":"");
246     if (flags & AF_ONEWAY_EXCEPTION) ret=g_strconcat_printf(ret,"%sAF_ONEWAY_EXCEPTION",ret?"|":"");
247     if (flags & AF_SPEED_LIMIT) ret=g_strconcat_printf(ret,"%sAF_SPEED_LIMIT",ret?"|":"");
248     if (flags & AF_RESERVED1) ret=g_strconcat_printf(ret,"%sAF_RESERVED1",ret?"|":"");
249     if (flags & AF_SIZE_OR_WEIGHT_LIMIT) ret=g_strconcat_printf(ret,"%sAF_SIZE_OR_WEIGHT_LIMIT",ret?"|":"");
250     if (flags & AF_THROUGH_TRAFFIC_LIMIT) ret=g_strconcat_printf(ret,"%sAF_THROUGH_TRAFFIC_LIMIT",ret?"|":"");
251     if (flags & AF_TOLL) ret=g_strconcat_printf(ret,"%sAF_TOLL",ret?"|":"");
252     if (flags & AF_SEASONAL) ret=g_strconcat_printf(ret,"%sAF_SEASONAL",ret?"|":"");
253     if (flags & AF_UNPAVED) ret=g_strconcat_printf(ret,"%sAF_UNPAVED",ret?"|":"");
254     if (flags & AF_FORD) ret=g_strconcat_printf(ret,"%sAF_FORD",ret?"|":"");
255     if (flags & AF_UNDERGROUND) ret=g_strconcat_printf(ret,"%sAF_UNDERGROUND",ret?"|":"");
256 zoff99 27 if (flags & AF_BRIDGE) ret=g_strconcat_printf(ret,"%sAF_BRIDGE",ret?"|":"");
257 zoff99 2 if (flags & AF_DANGEROUS_GOODS) ret=g_strconcat_printf(ret,"%sAF_DANGEROUS_GOODS",ret?"|":"");
258     if ((flags & AF_ALL) == AF_ALL)
259     return g_strconcat_printf(ret,"%sAF_ALL",ret?"|":"");
260     if ((flags & AF_ALL) == AF_MOTORIZED_FAST)
261     return g_strconcat_printf(ret,"%sAF_MOTORIZED_FAST",ret?"|":"");
262     if (flags & AF_EMERGENCY_VEHICLES) ret=g_strconcat_printf(ret,"%sAF_EMERGENCY_VEHICLES",ret?"|":"");
263     if (flags & AF_TRANSPORT_TRUCK) ret=g_strconcat_printf(ret,"%sAF_TRANSPORT_TRUCK",ret?"|":"");
264     if (flags & AF_DELIVERY_TRUCK) ret=g_strconcat_printf(ret,"%sAF_DELIVERY_TRUCK",ret?"|":"");
265     if (flags & AF_PUBLIC_BUS) ret=g_strconcat_printf(ret,"%sAF_PUBLIC_BUS",ret?"|":"");
266     if (flags & AF_TAXI) ret=g_strconcat_printf(ret,"%sAF_TAXI",ret?"|":"");
267     if (flags & AF_HIGH_OCCUPANCY_CAR) ret=g_strconcat_printf(ret,"%sAF_HIGH_OCCUPANCY_CAR",ret?"|":"");
268     if (flags & AF_CAR) ret=g_strconcat_printf(ret,"%sAF_CAR",ret?"|":"");
269     if (flags & AF_MOTORCYCLE) ret=g_strconcat_printf(ret,"%sAF_MOTORCYCLE",ret?"|":"");
270     if (flags & AF_MOPED) ret=g_strconcat_printf(ret,"%sAF_MOPED",ret?"|":"");
271     if (flags & AF_HORSE) ret=g_strconcat_printf(ret,"%sAF_HORSE",ret?"|":"");
272     if (flags & AF_BIKE) ret=g_strconcat_printf(ret,"%sAF_BIKE",ret?"|":"");
273     if (flags & AF_PEDESTRIAN) ret=g_strconcat_printf(ret,"%sAF_PEDESTRIAN",ret?"|":"");
274     return ret;
275     }
276    
277     char *
278     attr_to_text(struct attr *attr, struct map *map, int pretty)
279     {
280     char *ret;
281     enum attr_type type=attr->type;
282    
283     if (type >= attr_type_item_begin && type <= attr_type_item_end) {
284     struct item *item=attr->u.item;
285     struct attr type, data;
286     if (! item)
287     return g_strdup("(nil)");
288     if (! item->map || !map_get_attr(item->map, attr_type, &type, NULL))
289     type.u.str="";
290     if (! item->map || !map_get_attr(item->map, attr_data, &data, NULL))
291     data.u.str="";
292     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);
293     }
294     if (type >= attr_type_string_begin && type <= attr_type_string_end) {
295     if (map) {
296     char *mstr;
297     if (attr->u.str) {
298     mstr=map_convert_string(map, attr->u.str);
299     ret=g_strdup(mstr);
300     map_convert_free(mstr);
301     } else
302     ret=g_strdup("(null)");
303    
304     } else
305     ret=g_strdup(attr->u.str);
306     return ret;
307     }
308     if (type == attr_flags || type == attr_through_traffic_flags)
309     return flags_to_text(attr->u.num);
310     if (type >= attr_type_int_begin && type <= attr_type_int_end)
311     return g_strdup_printf("%d", attr->u.num);
312     if (type >= attr_type_int64_begin && type <= attr_type_int64_end)
313     return g_strdup_printf(LONGLONG_FMT, *attr->u.num64);
314     if (type >= attr_type_double_begin && type <= attr_type_double_end)
315     return g_strdup_printf("%f", *attr->u.numd);
316     if (type >= attr_type_object_begin && type <= attr_type_object_end)
317     return g_strdup_printf("(object[%s])", attr_to_name(type));
318     if (type >= attr_type_color_begin && type <= attr_type_color_end) {
319     if (attr->u.color->a != 65535)
320     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);
321     else
322     return g_strdup_printf("#%02x%02x%02x", attr->u.color->r>>8,attr->u.color->g>>8,attr->u.color->b>>8);
323     }
324     if (type >= attr_type_coord_geo_begin && type <= attr_type_coord_geo_end)
325     return g_strdup_printf("%f %f",attr->u.coord_geo->lng,attr->u.coord_geo->lat);
326     if (type == attr_zipfile_ref_block) {
327     int *data=attr->u.data;
328     return g_strdup_printf("0x%x,0x%x,0x%x",data[0],data[1],data[2]);
329     }
330     if (type == attr_item_id) {
331     int *data=attr->u.data;
332     return g_strdup_printf("0x%x,0x%x",data[0],data[1]);
333     }
334     if (type >= attr_type_group_begin && type <= attr_type_group_end) {
335     int i=0;
336     char *ret=g_strdup("");
337     char *sep="";
338     while (attr->u.attrs[i].type) {
339     char *val=attr_to_text(&attr->u.attrs[i], map, pretty);
340     ret=g_strconcat_printf(ret,"%s%s=%s",sep,attr_to_name(attr->u.attrs[i].type),val);
341     g_free(val);
342     sep=" ";
343     i++;
344     }
345     return ret;
346     }
347     if (type >= attr_type_item_type_begin && type <= attr_type_item_type_end) {
348     return g_strdup_printf("0x%x[%s]",attr->u.num,item_to_name(attr->u.num));
349     }
350     return g_strdup_printf("(no text[%s])", attr_to_name(type));
351     }
352    
353     struct attr *
354     attr_search(struct attr **attrs, struct attr *last, enum attr_type attr)
355     {
356     dbg(1, "enter attrs=%p\n", attrs);
357     while (*attrs) {
358     dbg(1,"*attrs=%p\n", *attrs);
359     if ((*attrs)->type == attr) {
360     return *attrs;
361     }
362     attrs++;
363     }
364     return NULL;
365     }
366    
367     static int
368     attr_match(enum attr_type search, enum attr_type found)
369     {
370     switch (search) {
371     case attr_any:
372     return 1;
373     case attr_any_xml:
374     switch (found) {
375     case attr_callback:
376     return 0;
377     default:
378     return 1;
379     }
380     default:
381     return search == found;
382     }
383     }
384    
385     int
386     attr_generic_get_attr(struct attr **attrs, struct attr **def_attrs, enum attr_type type, struct attr *attr, struct attr_iter *iter)
387     {
388     while (attrs && *attrs) {
389     if (attr_match(type,(*attrs)->type)) {
390     *attr=**attrs;
391     if (!iter)
392     return 1;
393     if (*((void **)iter) < (void *)attrs) {
394     *((void **)iter)=(void *)attrs;
395     return 1;
396     }
397     }
398     attrs++;
399     }
400     if (type == attr_any || type == attr_any_xml)
401     return 0;
402     while (def_attrs && *def_attrs) {
403     if ((*def_attrs)->type == type) {
404     *attr=**def_attrs;
405     return 1;
406     }
407     def_attrs++;
408     }
409     return 0;
410     }
411    
412     struct attr **
413     attr_generic_set_attr(struct attr **attrs, struct attr *attr)
414     {
415     struct attr **curr=attrs;
416     int i,count=0;
417     while (curr && *curr) {
418     if ((*curr)->type == attr->type) {
419     attr_free(*curr);
420     *curr=attr_dup(attr);
421     return attrs;
422     }
423     curr++;
424     count++;
425     }
426     curr=g_new0(struct attr *, count+2);
427     for (i = 0 ; i < count ; i++)
428     curr[i]=attrs[i];
429     curr[count]=attr_dup(attr);
430     curr[count+1]=NULL;
431     g_free(attrs);
432     return curr;
433     }
434    
435     struct attr **
436     attr_generic_add_attr(struct attr **attrs, struct attr *attr)
437     {
438     struct attr **curr=attrs;
439     int i,count=0;
440     while (curr && *curr) {
441     curr++;
442     count++;
443     }
444     curr=g_new0(struct attr *, count+2);
445     for (i = 0 ; i < count ; i++)
446     curr[i]=attrs[i];
447     curr[count]=attr_dup(attr);
448     curr[count+1]=NULL;
449     g_free(attrs);
450     return curr;
451     }
452    
453     struct attr **
454     attr_generic_remove_attr(struct attr **attrs, struct attr *attr)
455     {
456     struct attr **curr=attrs;
457     int i,j,count=0,found=0;
458     while (curr && *curr) {
459     if ((*curr)->type == attr->type && (*curr)->u.data == attr->u.data)
460     found=1;
461     curr++;
462     count++;
463     }
464     if (!found)
465     return attrs;
466     curr=g_new0(struct attr *, count);
467     j=0;
468     for (i = 0 ; i < count ; i++) {
469     if (attrs[i]->type != attr->type || attrs[i]->u.data != attr->u.data)
470     curr[j++]=attrs[i];
471     else
472     attr_free(attrs[i]);
473     }
474     curr[j]=NULL;
475     g_free(attrs);
476     return curr;
477     }
478    
479     enum attr_type
480     attr_type_begin(enum attr_type type)
481     {
482     if (type < attr_type_item_begin)
483     return attr_none;
484     if (type < attr_type_int_begin)
485     return attr_type_item_begin;
486     if (type < attr_type_string_begin)
487     return attr_type_int_begin;
488     if (type < attr_type_special_begin)
489     return attr_type_string_begin;
490     if (type < attr_type_double_begin)
491     return attr_type_special_begin;
492     if (type < attr_type_coord_geo_begin)
493     return attr_type_double_begin;
494     if (type < attr_type_color_begin)
495     return attr_type_coord_geo_begin;
496     if (type < attr_type_object_begin)
497     return attr_type_color_begin;
498     if (type < attr_type_coord_begin)
499     return attr_type_object_begin;
500     if (type < attr_type_pcoord_begin)
501     return attr_type_coord_begin;
502     if (type < attr_type_callback_begin)
503     return attr_type_pcoord_begin;
504     if (type < attr_type_int64_begin)
505     return attr_type_callback_begin;
506     if (type <= attr_type_int64_end)
507     return attr_type_int64_begin;
508     return attr_none;
509     }
510    
511     int
512     attr_data_size(struct attr *attr)
513     {
514     if (attr->type >= attr_type_string_begin && attr->type <= attr_type_string_end)
515     return strlen(attr->u.str)+1;
516     if (attr->type >= attr_type_int_begin && attr->type <= attr_type_int_end)
517     return sizeof(attr->u.num);
518     if (attr->type >= attr_type_coord_geo_begin && attr->type <= attr_type_coord_geo_end)
519     return sizeof(*attr->u.coord_geo);
520     if (attr->type >= attr_type_color_begin && attr->type <= attr_type_color_end)
521     return sizeof(*attr->u.color);
522     if (attr->type >= attr_type_object_begin && attr->type <= attr_type_object_end)
523     return sizeof(void *);
524     if (attr->type >= attr_type_item_begin && attr->type <= attr_type_item_end)
525     return sizeof(struct item);
526     if (attr->type >= attr_type_int64_begin && attr->type <= attr_type_int64_end)
527     return sizeof(*attr->u.num64);
528     if (attr->type == attr_order)
529     return sizeof(attr->u.range);
530     if (attr->type >= attr_type_double_begin && attr->type <= attr_type_double_end)
531     return sizeof(*attr->u.numd);
532     if (attr->type == attr_item_types) {
533     int i=0;
534     while (attr->u.item_types[i++] != type_none);
535     return i*sizeof(enum item_type);
536     }
537     if (attr->type >= attr_type_item_type_begin && attr->type <= attr_type_item_type_end)
538     return sizeof(enum item_type);
539     if (attr->type == attr_attr_types) {
540     int i=0;
541     while (attr->u.attr_types[i++] != attr_none);
542     return i*sizeof(enum attr_type);
543     }
544     dbg(0,"size for %s unknown\n", attr_to_name(attr->type));
545     return 0;
546     }
547    
548     void *
549     attr_data_get(struct attr *attr)
550     {
551     if ((attr->type >= attr_type_int_begin && attr->type <= attr_type_int_end) ||
552     (attr->type >= attr_type_item_type_begin && attr->type <= attr_type_item_type_end))
553     return &attr->u.num;
554     if (attr->type == attr_order)
555     return &attr->u.range;
556     return attr->u.data;
557     }
558    
559     void
560     attr_data_set(struct attr *attr, void *data)
561     {
562     if ((attr->type >= attr_type_int_begin && attr->type <= attr_type_int_end) ||
563     (attr->type >= attr_type_item_type_begin && attr->type <= attr_type_item_type_end))
564     attr->u.num=*((int *)data);
565     else
566     attr->u.data=data;
567     }
568    
569     void
570     attr_data_set_le(struct attr * attr, void * data)
571     {
572     if ((attr->type >= attr_type_int_begin && attr->type <= attr_type_int_end) ||
573     (attr->type >= attr_type_item_type_begin && attr->type <= attr_type_item_type_end))
574     attr->u.num=le32_to_cpu(*((int *)data));
575     else if (attr->type == attr_order) {
576     attr->u.num=le32_to_cpu(*((int *)data));
577     attr->u.range.min=le16_to_cpu(attr->u.range.min);
578     attr->u.range.max=le16_to_cpu(attr->u.range.max);
579     }
580     else
581     /* Fixme: Handle long long */
582     attr->u.data=data;
583    
584     }
585    
586     void
587     attr_free(struct attr *attr)
588     {
589     if (!attr)
590     return;
591     if (!(attr->type >= attr_type_int_begin && attr->type <= attr_type_int_end) &&
592     !(attr->type >= attr_type_object_begin && attr->type <= attr_type_object_end))
593     g_free(attr->u.data);
594     g_free(attr);
595     }
596    
597     void
598     attr_dup_content(struct attr *src, struct attr *dst)
599     {
600 zoff99 27 // dbg(0,"enter\n");
601 zoff99 2 int size;
602     dst->type=src->type;
603     if (src->type >= attr_type_int_begin && src->type <= attr_type_int_end)
604     dst->u.num=src->u.num;
605     else if (src->type >= attr_type_object_begin && src->type <= attr_type_object_end)
606     dst->u.data=src->u.data;
607     else {
608     size=attr_data_size(src);
609     if (size) {
610     dst->u.data=g_malloc(size);
611     memcpy(dst->u.data, src->u.data, size);
612     }
613     }
614 zoff99 27 // dbg(0,"leave\n");
615 zoff99 2 }
616    
617     struct attr *
618     attr_dup(struct attr *attr)
619     {
620     struct attr *ret=g_new0(struct attr, 1);
621     attr_dup_content(attr, ret);
622     return ret;
623     }
624    
625     void
626     attr_list_free(struct attr **attrs)
627     {
628     int count=0;
629     while (attrs && attrs[count]) {
630     attr_free(attrs[count++]);
631     }
632     g_free(attrs);
633     }
634    
635     struct attr **
636     attr_list_dup(struct attr **attrs)
637     {
638     struct attr **ret=attrs;
639     int i,count=0;
640    
641     while (attrs[count])
642 zoff99 27 {
643 zoff99 2 count++;
644 zoff99 27 }
645 zoff99 2 ret=g_new0(struct attr *, count+1);
646     for (i = 0 ; i < count ; i++)
647 zoff99 27 {
648 zoff99 2 ret[i]=attr_dup(attrs[i]);
649 zoff99 27 }
650 zoff99 2 return ret;
651     }
652    
653    
654     int
655     attr_from_line(char *line, char *name, int *pos, char *val_ret, char *name_ret)
656     {
657     int len=0,quoted;
658     char *p,*e,*n;
659    
660 zoff99 28 // dbg(1,"get_tag %s from %s\n", name, line);
661 zoff99 2 if (name)
662     len=strlen(name);
663     if (pos)
664     p=line+*pos;
665     else
666     p=line;
667     for(;;) {
668     while (*p == ' ') {
669     p++;
670     }
671     if (! *p)
672     return 0;
673     n=p;
674     e=strchr(p,'=');
675     if (! e)
676     return 0;
677     p=e+1;
678     quoted=0;
679     while (*p) {
680     if (*p == ' ' && !quoted)
681     break;
682     if (*p == '"')
683     quoted=1-quoted;
684     p++;
685     }
686     if (name == NULL || (e-n == len && !strncmp(n, name, len))) {
687     if (name_ret) {
688     len=e-n;
689     strncpy(name_ret, n, len);
690     name_ret[len]='\0';
691     }
692     e++;
693     len=p-e;
694     if (e[0] == '"') {
695     e++;
696     len-=2;
697     }
698     strncpy(val_ret, e, len);
699     val_ret[len]='\0';
700     if (pos)
701     *pos=p-line;
702     return 1;
703     }
704     }
705     return 0;
706     }
707    
708     /**
709     * Check if an enumeration of attribute types contains a specific attribute.
710     *
711     * @param types Pointer to the attr_type enumeration to be searched
712     * @param type The attr_type to be searched for
713     *
714     * @return 1 if the attribute type was found, 0 if it was not found or if a null pointer was passed as types
715     */
716     int
717     attr_types_contains(enum attr_type *types, enum attr_type type)
718     {
719     while (types && *types != attr_none) {
720     if (*types == type)
721     return 1;
722     types++;
723     }
724     return 0;
725     }
726    
727     /**
728     * Check if an enumeration of attribute types contains a specific attribute.
729     * It is different from attr_types_contains in that it returns a caller-defined value if the pointer to the enumeration is NULL.
730     *
731     * @param types Pointer to the attr_type enumeration to be searched
732     * @param type The attr_type to be searched for
733     * @param deflt The default value to return if types is NULL.
734     *
735     * @return 1 if the attribute type was found, 0 if it was not found, the value of the deflt argument if types is NULL.
736     */
737     int
738     attr_types_contains_default(enum attr_type *types, enum attr_type type, int deflt)
739     {
740     if (!types) {
741     return deflt;
742     }
743     return attr_types_contains(types, type);
744     }

   
Visit the ZANavi Wiki