]>
Commit | Line | Data |
---|---|---|
0d71302e BP |
1 | /* |
2 | * Copyright (c) 2017-2018 Nicira, Inc. | |
3 | * | |
4 | * Licensed under the Apache License, Version 2.0 (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: | |
7 | * | |
8 | * http://www.apache.org/licenses/LICENSE-2.0 | |
9 | * | |
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. | |
15 | */ | |
16 | ||
17 | #include <config.h> | |
18 | #include "openvswitch/namemap.h" | |
19 | #include <ctype.h> | |
20 | #include "hash.h" | |
21 | #include "openvswitch/dynamic-string.h" | |
22 | #include "openvswitch/json.h" | |
23 | ||
24 | void | |
25 | namemap_init(struct namemap *map) | |
26 | { | |
27 | hmap_init(&map->by_name); | |
28 | hmap_init(&map->by_number); | |
29 | } | |
30 | ||
31 | struct namemap_node * | |
32 | namemap_find_by_name(const struct namemap *map, const char *name) | |
33 | { | |
34 | struct namemap_node *node; | |
35 | ||
36 | HMAP_FOR_EACH_WITH_HASH (node, name_node, hash_string(name, 0), | |
37 | &map->by_name) { | |
38 | if (!strcmp(name, node->name)) { | |
39 | return node; | |
40 | } | |
41 | } | |
42 | return NULL; | |
43 | } | |
44 | ||
45 | struct namemap_node * | |
46 | namemap_find_by_number(const struct namemap *map, uint32_t number) | |
47 | { | |
48 | struct namemap_node *node; | |
49 | ||
50 | HMAP_FOR_EACH_IN_BUCKET (node, number_node, hash_int(number, 0), | |
51 | &map->by_number) { | |
52 | if (node->number == number) { | |
53 | return node; | |
54 | } | |
55 | } | |
56 | return NULL; | |
57 | } | |
58 | ||
59 | void | |
60 | namemap_put(struct namemap *map, uint32_t number, const char *name) | |
61 | { | |
62 | struct namemap_node *node; | |
63 | ||
64 | /* Look for duplicate name. */ | |
65 | node = namemap_find_by_name(map, name); | |
66 | if (node) { | |
67 | if (node->number != number) { | |
68 | node->duplicate = true; | |
69 | } | |
70 | return; | |
71 | } | |
72 | ||
73 | /* Look for duplicate number. */ | |
74 | node = namemap_find_by_number(map, number); | |
75 | if (node) { | |
76 | node->duplicate = true; | |
77 | return; | |
78 | } | |
79 | ||
80 | /* Add new node. */ | |
81 | node = xmalloc(sizeof *node); | |
82 | hmap_insert(&map->by_number, &node->number_node, hash_int(number, 0)); | |
83 | hmap_insert(&map->by_name, &node->name_node, hash_string(name, 0)); | |
84 | node->number = number; | |
85 | node->name = xstrdup(name); | |
86 | node->duplicate = false; | |
87 | } | |
88 | ||
89 | void | |
90 | namemap_destroy(struct namemap *map) | |
91 | { | |
92 | if (map) { | |
93 | struct namemap_node *node, *next; | |
94 | ||
95 | HMAP_FOR_EACH_SAFE (node, next, name_node, &map->by_name) { | |
96 | hmap_remove(&map->by_name, &node->name_node); | |
97 | hmap_remove(&map->by_number, &node->number_node); | |
98 | free(node->name); | |
99 | free(node); | |
100 | } | |
101 | hmap_destroy(&map->by_name); | |
102 | hmap_destroy(&map->by_number); | |
103 | } | |
104 | } | |
105 | ||
106 | /* A table or port name doesn't need to be quoted if it is alphanumeric and | |
107 | * starts with a letter. */ | |
108 | static bool | |
109 | name_needs_quotes(const char *name) | |
110 | { | |
111 | if (!isalpha((unsigned char) name[0])) { | |
112 | return true; | |
113 | } | |
114 | ||
115 | for (const char *p = name + 1; *p; p++) { | |
116 | if (!isalnum((unsigned char) *p)) { | |
117 | return true; | |
118 | } | |
119 | } | |
120 | return false; | |
121 | } | |
122 | ||
123 | /* Appends port or table 'name' to 's', quoting it if necessary. */ | |
124 | void | |
125 | namemap_put_name(const char *name, struct ds *s) | |
126 | { | |
127 | if (name_needs_quotes(name)) { | |
128 | json_string_escape(name, s); | |
129 | } else { | |
130 | ds_put_cstr(s, name); | |
131 | } | |
132 | } |