blob: cb8759b34ae4d5cee68c3bb2a12f3ecbba66145d [file] [log] [blame]
Jeff Thompson25b4e612013-10-10 16:03:24 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
Jeff Thompson47eecfc2013-07-07 22:56:46 -07002/**
Jeff Thompson7687dc02013-09-13 11:54:07 -07003 * Copyright (C) 2013 Regents of the University of California.
4 * @author: Jeff Thompson <jefft0@remap.ucla.edu>
Jeff Thompsona98000c2013-12-16 14:40:09 -08005 * @author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
Jeff Thompson47eecfc2013-07-07 22:56:46 -07006 * See COPYING for copyright and distribution information.
Jeff Thompson9c41dfe2013-06-27 12:10:25 -07007 */
8
Alexander Afanasyeve2dcdfd2014-02-07 15:53:28 -08009#include "common.hpp"
10
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -080011#include "name.hpp"
12
Jeff Thompsonb8f1b132013-08-13 11:07:43 -070013#include <algorithm>
Alexander Afanasyev1e0a0772014-01-28 20:07:07 -080014#include <cstring>
Jeff Thompson9c41dfe2013-06-27 12:10:25 -070015
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -080016#include "util/time.hpp"
Alexander Afanasyevaf283d82014-01-03 13:23:34 -080017#include "util/string-helper.hpp"
18
Jeff Thompson9c41dfe2013-06-27 12:10:25 -070019namespace ndn {
20
Jeff Thompson25b4e612013-10-10 16:03:24 -070021void
Jeff Thompson0050abe2013-09-17 12:50:25 -070022Name::set(const char *uri_cstr)
Jeff Thompson443398d2013-07-02 19:45:46 -070023{
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -080024 clear();
Jeff Thompson67515bd2013-08-15 17:43:22 -070025
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -080026 std::string uri = uri_cstr;
Jeff Thompson443398d2013-07-02 19:45:46 -070027 trim(uri);
28 if (uri.size() == 0)
29 return;
30
31 size_t iColon = uri.find(':');
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -080032 if (iColon != std::string::npos) {
Jeff Thompson443398d2013-07-02 19:45:46 -070033 // Make sure the colon came before a '/'.
34 size_t iFirstSlash = uri.find('/');
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -080035 if (iFirstSlash == std::string::npos || iColon < iFirstSlash) {
Jeff Thompson443398d2013-07-02 19:45:46 -070036 // Omit the leading protocol such as ndn:
37 uri.erase(0, iColon + 1);
38 trim(uri);
39 }
40 }
41
42 // Trim the leading slash and possibly the authority.
43 if (uri[0] == '/') {
44 if (uri.size() >= 2 && uri[1] == '/') {
45 // Strip the authority following "//".
46 size_t iAfterAuthority = uri.find('/', 2);
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -080047 if (iAfterAuthority == std::string::npos)
Jeff Thompson443398d2013-07-02 19:45:46 -070048 // Unusual case: there was only an authority.
49 return;
50 else {
51 uri.erase(0, iAfterAuthority + 1);
52 trim(uri);
53 }
54 }
55 else {
56 uri.erase(0, 1);
57 trim(uri);
58 }
59 }
60
61 size_t iComponentStart = 0;
62
63 // Unescape the components.
64 while (iComponentStart < uri.size()) {
65 size_t iComponentEnd = uri.find("/", iComponentStart);
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -080066 if (iComponentEnd == std::string::npos)
Jeff Thompson443398d2013-07-02 19:45:46 -070067 iComponentEnd = uri.size();
68
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -080069 Component component = Component::fromEscapedString(&uri[0], iComponentStart, iComponentEnd);
Jeff Thompson46411c92013-09-13 19:31:25 -070070 // Ignore illegal components. This also gets rid of a trailing '/'.
Alexander Afanasyevaf283d82014-01-03 13:23:34 -080071 if (!component.empty())
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -080072 append(Component(component));
Jeff Thompson443398d2013-07-02 19:45:46 -070073
74 iComponentStart = iComponentEnd + 1;
75 }
76}
77
Jeff Thompson26b0d792013-09-23 16:19:01 -070078Name&
79Name::append(const Name& name)
80{
81 if (&name == this)
82 // Copying from this name, so need to make a copy first.
83 return append(Name(name));
84
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -080085 for (size_t i = 0; i < name.size(); ++i)
86 append(name.at(i));
Jeff Thompson26b0d792013-09-23 16:19:01 -070087
88 return *this;
89}
90
Jeff Thompsond0159d72013-09-23 13:34:15 -070091Name
92Name::getSubName(size_t iStartComponent, size_t nComponents) const
93{
94 Name result;
95
Jeff Thompson97223af2013-09-24 17:01:27 -070096 size_t iEnd = iStartComponent + nComponents;
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -080097 for (size_t i = iStartComponent; i < iEnd && i < size(); ++i)
98 result.append(at(i));
Jeff Thompsond0159d72013-09-23 13:34:15 -070099
100 return result;
101}
102
103Name
104Name::getSubName(size_t iStartComponent) const
105{
106 Name result;
107
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800108 for (size_t i = iStartComponent; i < size(); ++i)
109 result.append(at(i));
Jeff Thompsond0159d72013-09-23 13:34:15 -0700110
111 return result;
112}
113
Jeff Thompson0050abe2013-09-17 12:50:25 -0700114bool
Jeff Thompson3c2ab012013-10-02 14:18:16 -0700115Name::equals(const Name& name) const
116{
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800117 if (size() != name.size())
Jeff Thompson3c2ab012013-10-02 14:18:16 -0700118 return false;
119
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800120 for (size_t i = 0; i < size(); ++i) {
121 if (at(i) != name.at(i))
Jeff Thompson3c2ab012013-10-02 14:18:16 -0700122 return false;
123 }
124
Jeff Thompsone589c3f2013-10-12 17:30:50 -0700125 return true;
Jeff Thompson3c2ab012013-10-02 14:18:16 -0700126}
127
128bool
Alexander Afanasyevaf283d82014-01-03 13:23:34 -0800129Name::isPrefixOf(const Name& name) const
Jeff Thompsoncc35cd42013-08-20 12:23:14 -0700130{
Jeff Thompsone589c3f2013-10-12 17:30:50 -0700131 // This name is longer than the name we are checking it against.
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800132 if (size() > name.size())
Jeff Thompson3c2ab012013-10-02 14:18:16 -0700133 return false;
Jeff Thompsoncc35cd42013-08-20 12:23:14 -0700134
Jeff Thompsone589c3f2013-10-12 17:30:50 -0700135 // Check if at least one of given components doesn't match.
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800136 for (size_t i = 0; i < size(); ++i) {
137 if (at(i) != name.at(i))
Jeff Thompsoncc35cd42013-08-20 12:23:14 -0700138 return false;
139 }
140
Jeff Thompsone589c3f2013-10-12 17:30:50 -0700141 return true;
Jeff Thompsoncc35cd42013-08-20 12:23:14 -0700142}
143
Jeff Thompsonec7789a2013-08-21 11:08:36 -0700144
Jeff Thompsonafc45a92014-01-15 12:42:45 -0800145int
146Name::compare(const Name& other) const
Jeff Thompson82568ad2013-12-17 15:17:40 -0800147{
Jeff Thompsonafc45a92014-01-15 12:42:45 -0800148 for (size_t i = 0; i < size() && i < other.size(); ++i) {
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800149 int comparison = at(i).compare(other.at(i));
Jeff Thompsonafc45a92014-01-15 12:42:45 -0800150 if (comparison == 0)
Jeff Thompson82568ad2013-12-17 15:17:40 -0800151 // The components at this index are equal, so check the next components.
152 continue;
153
154 // Otherwise, the result is based on the components at this index.
Jeff Thompsonafc45a92014-01-15 12:42:45 -0800155 return comparison;
Jeff Thompson82568ad2013-12-17 15:17:40 -0800156 }
157
Jeff Thompsonafc45a92014-01-15 12:42:45 -0800158 // The components up to min(this.size(), other.size()) are equal, so the shorter name is less.
159 if (size() < other.size())
160 return -1;
161 else if (size() > other.size())
162 return 1;
163 else
164 return 0;
Jeff Thompson82568ad2013-12-17 15:17:40 -0800165}
166
Alexander Afanasyevaf283d82014-01-03 13:23:34 -0800167std::ostream&
168operator << (std::ostream& os, const Name& name)
169{
170 if (name.empty())
171 {
172 os << "/";
173 }
174 else
175 {
176 for (Name::const_iterator i = name.begin(); i != name.end(); i++) {
177 os << "/";
178 i->toEscapedString(os);
179 }
180 }
181
182 return os;
183}
Jeff Thompson82568ad2013-12-17 15:17:40 -0800184
Wentao Shang77949212014-02-01 23:42:24 -0800185} // namespace ndn