00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <config.h>
00025 #include "dbus-address.h"
00026 #include "dbus-internals.h"
00027 #include "dbus-list.h"
00028
00036 struct DBusAddressEntry
00037 {
00038 DBusString method;
00039
00040 DBusList *keys;
00041 DBusList *values;
00042 };
00043
00044 static void
00045 dbus_address_entry_free (DBusAddressEntry *entry)
00046 {
00047 DBusList *link;
00048
00049 _dbus_string_free (&entry->method);
00050
00051 link = _dbus_list_get_first_link (&entry->keys);
00052 while (link != NULL)
00053 {
00054 _dbus_string_free (link->data);
00055 dbus_free (link->data);
00056
00057 link = _dbus_list_get_next_link (&entry->keys, link);
00058 }
00059 _dbus_list_clear (&entry->keys);
00060
00061 link = _dbus_list_get_first_link (&entry->values);
00062 while (link != NULL)
00063 {
00064 _dbus_string_free (link->data);
00065 dbus_free (link->data);
00066
00067 link = _dbus_list_get_next_link (&entry->values, link);
00068 }
00069 _dbus_list_clear (&entry->values);
00070
00071 dbus_free (entry);
00072 }
00073
00074
00080 void
00081 dbus_address_entries_free (DBusAddressEntry **entries)
00082 {
00083 int i;
00084
00085 for (i = 0; entries[i] != NULL; i++)
00086 dbus_address_entry_free (entries[i]);
00087 dbus_free (entries);
00088 }
00089
00090 static DBusAddressEntry *
00091 create_entry (void)
00092 {
00093 DBusAddressEntry *entry;
00094
00095 entry = dbus_new0 (DBusAddressEntry, 1);
00096
00097 if (entry == NULL)
00098 return NULL;
00099
00100 if (!_dbus_string_init (&entry->method))
00101 {
00102 dbus_free (entry);
00103 return NULL;
00104 }
00105
00106 return entry;
00107 }
00108
00116 const char *
00117 dbus_address_entry_get_method (DBusAddressEntry *entry)
00118 {
00119 return _dbus_string_get_const_data (&entry->method);
00120 }
00121
00129 const char *
00130 dbus_address_entry_get_value (DBusAddressEntry *entry,
00131 const char *key)
00132 {
00133 DBusList *values, *keys;
00134
00135 keys = _dbus_list_get_first_link (&entry->keys);
00136 values = _dbus_list_get_first_link (&entry->values);
00137
00138 while (keys != NULL)
00139 {
00140 _dbus_assert (values != NULL);
00141
00142 if (_dbus_string_equal_c_str (keys->data, key))
00143 return _dbus_string_get_const_data (values->data);
00144
00145 keys = _dbus_list_get_next_link (&entry->keys, keys);
00146 values = _dbus_list_get_next_link (&entry->values, values);
00147 }
00148
00149 return NULL;
00150 }
00151
00168 dbus_bool_t
00169 dbus_parse_address (const char *address,
00170 DBusAddressEntry ***entry,
00171 int *array_len,
00172 DBusError *error)
00173 {
00174 DBusString str;
00175 int pos, end_pos, len, i;
00176 DBusList *entries, *link;
00177 DBusAddressEntry **entry_array;
00178
00179 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00180
00181 _dbus_string_init_const (&str, address);
00182
00183 entries = NULL;
00184 pos = 0;
00185 len = _dbus_string_get_length (&str);
00186
00187 while (pos < len)
00188 {
00189 DBusAddressEntry *entry;
00190
00191 int found_pos;
00192
00193 entry = create_entry ();
00194 if (!entry)
00195 {
00196 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00197
00198 goto error;
00199 }
00200
00201
00202 if (!_dbus_list_append (&entries, entry))
00203 {
00204 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00205 dbus_address_entry_free (entry);
00206 goto error;
00207 }
00208
00209
00210 if (!_dbus_string_find (&str, pos, ";", &end_pos))
00211 end_pos = len;
00212
00213
00214 if (!_dbus_string_find_to (&str, pos, end_pos, ":", &found_pos))
00215 {
00216 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS, "Address does not contain a colon");
00217 goto error;
00218 }
00219
00220 if (!_dbus_string_copy_len (&str, pos, found_pos - pos, &entry->method, 0))
00221 {
00222 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00223 goto error;
00224 }
00225
00226 pos = found_pos + 1;
00227
00228 while (pos < end_pos)
00229 {
00230 int comma_pos, equals_pos;
00231
00232 if (!_dbus_string_find_to (&str, pos, end_pos, ",", &comma_pos))
00233 comma_pos = end_pos;
00234
00235 if (!_dbus_string_find_to (&str, pos, comma_pos, "=", &equals_pos) ||
00236 equals_pos == pos || equals_pos + 1 == comma_pos)
00237 {
00238 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
00239 "'=' character not found or has no value following it");
00240 goto error;
00241 }
00242 else
00243 {
00244 DBusString *key;
00245 DBusString *value;
00246
00247 key = dbus_new0 (DBusString, 1);
00248
00249 if (!key)
00250 {
00251 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00252 goto error;
00253 }
00254
00255 value = dbus_new0 (DBusString, 1);
00256 if (!value)
00257 {
00258 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00259 dbus_free (key);
00260 goto error;
00261 }
00262
00263 if (!_dbus_string_init (key))
00264 {
00265 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00266 dbus_free (key);
00267 dbus_free (value);
00268
00269 goto error;
00270 }
00271
00272 if (!_dbus_string_init (value))
00273 {
00274 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00275 _dbus_string_free (key);
00276
00277 dbus_free (key);
00278 dbus_free (value);
00279 goto error;
00280 }
00281
00282 if (!_dbus_string_copy_len (&str, pos, equals_pos - pos, key, 0))
00283 {
00284 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00285 _dbus_string_free (key);
00286 _dbus_string_free (value);
00287
00288 dbus_free (key);
00289 dbus_free (value);
00290 goto error;
00291 }
00292
00293 if (!_dbus_string_copy_len (&str, equals_pos + 1, comma_pos - equals_pos - 1, value, 0))
00294 {
00295 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00296 _dbus_string_free (key);
00297 _dbus_string_free (value);
00298
00299 dbus_free (key);
00300 dbus_free (value);
00301 goto error;
00302 }
00303
00304 if (!_dbus_list_append (&entry->keys, key))
00305 {
00306 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00307 _dbus_string_free (key);
00308 _dbus_string_free (value);
00309
00310 dbus_free (key);
00311 dbus_free (value);
00312 goto error;
00313 }
00314
00315 if (!_dbus_list_append (&entry->values, value))
00316 {
00317 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00318 _dbus_string_free (value);
00319
00320 dbus_free (value);
00321 goto error;
00322 }
00323 }
00324
00325 pos = comma_pos + 1;
00326 }
00327
00328 pos = end_pos + 1;
00329 }
00330
00331 *array_len = _dbus_list_get_length (&entries);
00332
00333 entry_array = dbus_new (DBusAddressEntry *, *array_len + 1);
00334
00335 if (!entry_array)
00336 {
00337 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00338
00339 goto error;
00340 }
00341
00342 entry_array [*array_len] = NULL;
00343
00344 link = _dbus_list_get_first_link (&entries);
00345 i = 0;
00346 while (link != NULL)
00347 {
00348 entry_array[i] = link->data;
00349 i++;
00350 link = _dbus_list_get_next_link (&entries, link);
00351 }
00352
00353 _dbus_list_clear (&entries);
00354 *entry = entry_array;
00355
00356 return TRUE;
00357
00358 error:
00359
00360 link = _dbus_list_get_first_link (&entries);
00361 while (link != NULL)
00362 {
00363 dbus_address_entry_free (link->data);
00364 link = _dbus_list_get_next_link (&entries, link);
00365 }
00366
00367 _dbus_list_clear (&entries);
00368
00369 return FALSE;
00370
00371 }
00372
00373
00376 #ifdef DBUS_BUILD_TESTS
00377 #include "dbus-test.h"
00378
00379 dbus_bool_t
00380 _dbus_address_test (void)
00381 {
00382 DBusAddressEntry **entries;
00383 int len;
00384 DBusError error;
00385
00386 dbus_error_init (&error);
00387
00388 if (!dbus_parse_address ("unix:path=/tmp/foo;debug:name=test,sliff=sloff;",
00389 &entries, &len, &error))
00390 _dbus_assert_not_reached ("could not parse address");
00391 _dbus_assert (len == 2);
00392 _dbus_assert (strcmp (dbus_address_entry_get_value (entries[0], "path"), "/tmp/foo") == 0);
00393 _dbus_assert (strcmp (dbus_address_entry_get_value (entries[1], "name"), "test") == 0);
00394 _dbus_assert (strcmp (dbus_address_entry_get_value (entries[1], "sliff"), "sloff") == 0);
00395
00396 dbus_address_entries_free (entries);
00397
00398
00399 if (dbus_parse_address ("foo", &entries, &len, &error))
00400 _dbus_assert_not_reached ("Parsed incorrect address.");
00401 else
00402 dbus_error_free (&error);
00403
00404 if (dbus_parse_address ("foo:bar", &entries, &len, &error))
00405 _dbus_assert_not_reached ("Parsed incorrect address.");
00406 else
00407 dbus_error_free (&error);
00408
00409 if (dbus_parse_address ("foo:bar,baz", &entries, &len, &error))
00410 _dbus_assert_not_reached ("Parsed incorrect address.");
00411 else
00412 dbus_error_free (&error);
00413
00414 if (dbus_parse_address ("foo:bar=foo,baz", &entries, &len, &error))
00415 _dbus_assert_not_reached ("Parsed incorrect address.");
00416 else
00417 dbus_error_free (&error);
00418
00419 if (dbus_parse_address ("foo:bar=foo;baz", &entries, &len, &error))
00420 _dbus_assert_not_reached ("Parsed incorrect address.");
00421 else
00422 dbus_error_free (&error);
00423
00424 if (dbus_parse_address ("foo:=foo", &entries, &len, &error))
00425 _dbus_assert_not_reached ("Parsed incorrect address.");
00426 else
00427 dbus_error_free (&error);
00428
00429 if (dbus_parse_address ("foo:foo=", &entries, &len, &error))
00430 _dbus_assert_not_reached ("Parsed incorrect address.");
00431 else
00432 dbus_error_free (&error);
00433
00434 if (dbus_parse_address ("foo:foo,bar=baz", &entries, &len, &error))
00435 _dbus_assert_not_reached ("Parsed incorrect address.");
00436 else
00437 dbus_error_free (&error);
00438
00439 return TRUE;
00440 }
00441
00442 #endif