Squashed 'third_party/rawrtc/re/' content from commit f3163ce8b

Change-Id: I6a235e6ac0f03269d951026f9d195da05c40fdab
git-subtree-dir: third_party/rawrtc/re
git-subtree-split: f3163ce8b526a13b35ef71ce4dd6f43585064d8a
diff --git a/src/uri/ucmp.c b/src/uri/ucmp.c
new file mode 100644
index 0000000..7112212
--- /dev/null
+++ b/src/uri/ucmp.c
@@ -0,0 +1,110 @@
+/**
+ * @file ucmp.c  URI comparison
+ *
+ * Copyright (C) 2010 Creytiv.com
+ */
+#include <re_types.h>
+#include <re_fmt.h>
+#include <re_uri.h>
+
+
+static int param_handler(const struct pl *pname, const struct pl *pvalue,
+			 void *arg)
+{
+	struct pl *other_params = arg;
+	struct pl other_pvalue = PL_INIT;
+	bool both;
+
+	if (0 == pl_strcmp(pname, "user"))
+		both = true;
+	else if (0 == pl_strcmp(pname, "ttl"))
+		both = true;
+	else if (0 == pl_strcmp(pname, "method"))
+		both = true;
+	else if (0 == pl_strcmp(pname, "maddr"))
+		both = true;
+	else if (0 == pl_strcmp(pname, "transport"))
+		both = true;
+	else
+		both = false;
+
+	if (uri_param_get(other_params, pname, &other_pvalue))
+		return both ? ENOENT : 0;
+
+	return pl_casecmp(pvalue, &other_pvalue);
+}
+
+
+static int header_handler(const struct pl *hname, const struct pl *hvalue,
+			  void *arg)
+{
+	struct pl *other_headers = arg;
+	struct pl other_hvalue;
+	int err;
+
+	err = uri_header_get(other_headers, hname, &other_hvalue);
+	if (err)
+		return err;
+
+	return pl_casecmp(hvalue, &other_hvalue);
+}
+
+
+/**
+ * Compare two URIs - see RFC 3261 Section 19.1.4
+ *
+ * @param l  Left-hand URI object
+ * @param r  Right-hand URI object
+ *
+ * @return true if match, otherwise false
+ */
+bool uri_cmp(const struct uri *l, const struct uri *r)
+{
+	int err;
+
+	if (!l || !r)
+		return false;
+
+	if (l == r)
+		return true;
+
+	/* A SIP and SIPS URI are never equivalent. */
+	if (pl_casecmp(&l->scheme, &r->scheme))
+		return false;
+
+	/* Comparison of the userinfo of SIP and SIPS URIs is case-sensitive */
+	if (pl_cmp(&l->user, &r->user))
+		return false;
+
+	if (pl_cmp(&l->password, &r->password))
+		return false;
+
+	if (pl_casecmp(&l->host, &r->host))
+		return false;
+	if (l->af != r->af)
+		return false;
+
+	if (l->port != r->port)
+		return false;
+
+	/* URI parameters */
+	err = uri_params_apply(&l->params, param_handler, (void *)&r->params);
+	if (err)
+		return false;
+	err = uri_params_apply(&r->params, param_handler, (void *)&l->params);
+	if (err)
+		return false;
+
+	/* URI headers */
+	err = uri_headers_apply(&l->headers, header_handler,
+				(void *)&r->headers);
+	if (err)
+		return false;
+	err = uri_headers_apply(&r->headers, header_handler,
+				(void *)&l->headers);
+	if (err)
+		return false;
+
+	/* Match */
+	return true;
+}