blob: 5f4a01885e42b2a05cc76bde5a6390cbd64a611e [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 Afanasyev95e8c2f2014-02-06 17:29:30 -08009#include "name.hpp"
10
Jeff Thompsonb8f1b132013-08-13 11:07:43 -070011#include <algorithm>
Alexander Afanasyev1e0a0772014-01-28 20:07:07 -080012#include <cstring>
Jeff Thompson9c41dfe2013-06-27 12:10:25 -070013
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -080014#include "util/time.hpp"
Alexander Afanasyevaf283d82014-01-03 13:23:34 -080015#include "util/string-helper.hpp"
16
Jeff Thompson9c41dfe2013-06-27 12:10:25 -070017namespace ndn {
18
Jeff Thompson25b4e612013-10-10 16:03:24 -070019void
Jeff Thompson0050abe2013-09-17 12:50:25 -070020Name::set(const char *uri_cstr)
Jeff Thompson443398d2013-07-02 19:45:46 -070021{
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -080022 clear();
Jeff Thompson67515bd2013-08-15 17:43:22 -070023
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -080024 std::string uri = uri_cstr;
Jeff Thompson443398d2013-07-02 19:45:46 -070025 trim(uri);
26 if (uri.size() == 0)
27 return;
28
29 size_t iColon = uri.find(':');
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -080030 if (iColon != std::string::npos) {
Jeff Thompson443398d2013-07-02 19:45:46 -070031 // Make sure the colon came before a '/'.
32 size_t iFirstSlash = uri.find('/');
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -080033 if (iFirstSlash == std::string::npos || iColon < iFirstSlash) {
Jeff Thompson443398d2013-07-02 19:45:46 -070034 // Omit the leading protocol such as ndn:
35 uri.erase(0, iColon + 1);
36 trim(uri);
37 }
38 }
39
40 // Trim the leading slash and possibly the authority.
41 if (uri[0] == '/') {
42 if (uri.size() >= 2 && uri[1] == '/') {
43 // Strip the authority following "//".
44 size_t iAfterAuthority = uri.find('/', 2);
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -080045 if (iAfterAuthority == std::string::npos)
Jeff Thompson443398d2013-07-02 19:45:46 -070046 // Unusual case: there was only an authority.
47 return;
48 else {
49 uri.erase(0, iAfterAuthority + 1);
50 trim(uri);
51 }
52 }
53 else {
54 uri.erase(0, 1);
55 trim(uri);
56 }
57 }
58
59 size_t iComponentStart = 0;
60
61 // Unescape the components.
62 while (iComponentStart < uri.size()) {
63 size_t iComponentEnd = uri.find("/", iComponentStart);
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -080064 if (iComponentEnd == std::string::npos)
Jeff Thompson443398d2013-07-02 19:45:46 -070065 iComponentEnd = uri.size();
66
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -080067 Component component = Component::fromEscapedString(&uri[0], iComponentStart, iComponentEnd);
Jeff Thompson46411c92013-09-13 19:31:25 -070068 // Ignore illegal components. This also gets rid of a trailing '/'.
Alexander Afanasyevaf283d82014-01-03 13:23:34 -080069 if (!component.empty())
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -080070 append(Component(component));
Jeff Thompson443398d2013-07-02 19:45:46 -070071
72 iComponentStart = iComponentEnd + 1;
73 }
74}
75
Jeff Thompson26b0d792013-09-23 16:19:01 -070076Name&
77Name::append(const Name& name)
78{
79 if (&name == this)
80 // Copying from this name, so need to make a copy first.
81 return append(Name(name));
82
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -080083 for (size_t i = 0; i < name.size(); ++i)
84 append(name.at(i));
Jeff Thompson26b0d792013-09-23 16:19:01 -070085
86 return *this;
87}
88
Alexander Afanasyev594cdb22014-01-03 15:11:33 -080089Name&
90Name::appendVersion()
91{
92 appendVersion(ndn_getNowMilliseconds());
93 return *this;
94}
95
Jeff Thompsond0159d72013-09-23 13:34:15 -070096Name
97Name::getSubName(size_t iStartComponent, size_t nComponents) const
98{
99 Name result;
100
Jeff Thompson97223af2013-09-24 17:01:27 -0700101 size_t iEnd = iStartComponent + nComponents;
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800102 for (size_t i = iStartComponent; i < iEnd && i < size(); ++i)
103 result.append(at(i));
Jeff Thompsond0159d72013-09-23 13:34:15 -0700104
105 return result;
106}
107
108Name
109Name::getSubName(size_t iStartComponent) const
110{
111 Name result;
112
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800113 for (size_t i = iStartComponent; i < size(); ++i)
114 result.append(at(i));
Jeff Thompsond0159d72013-09-23 13:34:15 -0700115
116 return result;
117}
118
Jeff Thompson0050abe2013-09-17 12:50:25 -0700119bool
Jeff Thompson3c2ab012013-10-02 14:18:16 -0700120Name::equals(const Name& name) const
121{
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800122 if (size() != name.size())
Jeff Thompson3c2ab012013-10-02 14:18:16 -0700123 return false;
124
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800125 for (size_t i = 0; i < size(); ++i) {
126 if (at(i) != name.at(i))
Jeff Thompson3c2ab012013-10-02 14:18:16 -0700127 return false;
128 }
129
Jeff Thompsone589c3f2013-10-12 17:30:50 -0700130 return true;
Jeff Thompson3c2ab012013-10-02 14:18:16 -0700131}
132
133bool
Alexander Afanasyevaf283d82014-01-03 13:23:34 -0800134Name::isPrefixOf(const Name& name) const
Jeff Thompsoncc35cd42013-08-20 12:23:14 -0700135{
Jeff Thompsone589c3f2013-10-12 17:30:50 -0700136 // This name is longer than the name we are checking it against.
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800137 if (size() > name.size())
Jeff Thompson3c2ab012013-10-02 14:18:16 -0700138 return false;
Jeff Thompsoncc35cd42013-08-20 12:23:14 -0700139
Jeff Thompsone589c3f2013-10-12 17:30:50 -0700140 // Check if at least one of given components doesn't match.
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800141 for (size_t i = 0; i < size(); ++i) {
142 if (at(i) != name.at(i))
Jeff Thompsoncc35cd42013-08-20 12:23:14 -0700143 return false;
144 }
145
Jeff Thompsone589c3f2013-10-12 17:30:50 -0700146 return true;
Jeff Thompsoncc35cd42013-08-20 12:23:14 -0700147}
148
Jeff Thompsonec7789a2013-08-21 11:08:36 -0700149
Jeff Thompsonafc45a92014-01-15 12:42:45 -0800150int
151Name::compare(const Name& other) const
Jeff Thompson82568ad2013-12-17 15:17:40 -0800152{
Jeff Thompsonafc45a92014-01-15 12:42:45 -0800153 for (size_t i = 0; i < size() && i < other.size(); ++i) {
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800154 int comparison = at(i).compare(other.at(i));
Jeff Thompsonafc45a92014-01-15 12:42:45 -0800155 if (comparison == 0)
Jeff Thompson82568ad2013-12-17 15:17:40 -0800156 // The components at this index are equal, so check the next components.
157 continue;
158
159 // Otherwise, the result is based on the components at this index.
Jeff Thompsonafc45a92014-01-15 12:42:45 -0800160 return comparison;
Jeff Thompson82568ad2013-12-17 15:17:40 -0800161 }
162
Jeff Thompsonafc45a92014-01-15 12:42:45 -0800163 // The components up to min(this.size(), other.size()) are equal, so the shorter name is less.
164 if (size() < other.size())
165 return -1;
166 else if (size() > other.size())
167 return 1;
168 else
169 return 0;
Jeff Thompson82568ad2013-12-17 15:17:40 -0800170}
171
Alexander Afanasyevaf283d82014-01-03 13:23:34 -0800172std::ostream&
173operator << (std::ostream& os, const Name& name)
174{
175 if (name.empty())
176 {
177 os << "/";
178 }
179 else
180 {
181 for (Name::const_iterator i = name.begin(); i != name.end(); i++) {
182 os << "/";
183 i->toEscapedString(os);
184 }
185 }
186
187 return os;
188}
Jeff Thompson82568ad2013-12-17 15:17:40 -0800189
Alexander Afanasyev848c61a2014-01-03 13:52:04 -0800190const Block &
191Name::wireEncode() const
192{
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800193 if (m_nameBlock.hasWire())
194 return m_nameBlock;
Alexander Afanasyev848c61a2014-01-03 13:52:04 -0800195
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800196 for (Block::element_iterator i = m_nameBlock.element_begin();
197 i != m_nameBlock.element_end();
198 ++i)
199 {
200 i->encode();
201 }
Alexander Afanasyev848c61a2014-01-03 13:52:04 -0800202
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800203 m_nameBlock.encode();
204 return m_nameBlock;
Alexander Afanasyev848c61a2014-01-03 13:52:04 -0800205}
206
207void
208Name::wireDecode(const Block &wire)
209{
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800210 m_nameBlock = wire;
211 m_nameBlock.parse();
Alexander Afanasyev848c61a2014-01-03 13:52:04 -0800212}
Wentao Shang77949212014-02-01 23:42:24 -0800213
Wentao Shang77949212014-02-01 23:42:24 -0800214size_t
215Name::wireEncode (EncodingBuffer& blk)
216{
217 size_t total_len = 0;
218
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800219 for (reverse_iterator i = rbegin ();
220 i != rend ();
Wentao Shang77949212014-02-01 23:42:24 -0800221 ++i)
222 {
223 total_len += i->wireEncode (blk);
224 }
225
226 total_len += blk.prependVarNumber (total_len);
227 total_len += blk.prependVarNumber (Tlv::Name);
228 return total_len;
Jeff Thompson9c41dfe2013-06-27 12:10:25 -0700229}
Wentao Shang77949212014-02-01 23:42:24 -0800230
231} // namespace ndn