blob: 846cabb547b23fadf137d750cc02afca10cb6c89 [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
Alexander Afanasyev594cdb22014-01-03 15:11:33 -080091Name&
92Name::appendVersion()
93{
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070094 appendVersion(time::toUnixTimestamp(time::system_clock::now()).count());
Alexander Afanasyev594cdb22014-01-03 15:11:33 -080095 return *this;
96}
97
Jeff Thompsond0159d72013-09-23 13:34:15 -070098Name
99Name::getSubName(size_t iStartComponent, size_t nComponents) const
100{
101 Name result;
102
Jeff Thompson97223af2013-09-24 17:01:27 -0700103 size_t iEnd = iStartComponent + nComponents;
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800104 for (size_t i = iStartComponent; i < iEnd && i < size(); ++i)
105 result.append(at(i));
Jeff Thompsond0159d72013-09-23 13:34:15 -0700106
107 return result;
108}
109
110Name
111Name::getSubName(size_t iStartComponent) const
112{
113 Name result;
114
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800115 for (size_t i = iStartComponent; i < size(); ++i)
116 result.append(at(i));
Jeff Thompsond0159d72013-09-23 13:34:15 -0700117
118 return result;
119}
120
Jeff Thompson0050abe2013-09-17 12:50:25 -0700121bool
Jeff Thompson3c2ab012013-10-02 14:18:16 -0700122Name::equals(const Name& name) const
123{
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800124 if (size() != name.size())
Jeff Thompson3c2ab012013-10-02 14:18:16 -0700125 return false;
126
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800127 for (size_t i = 0; i < size(); ++i) {
128 if (at(i) != name.at(i))
Jeff Thompson3c2ab012013-10-02 14:18:16 -0700129 return false;
130 }
131
Jeff Thompsone589c3f2013-10-12 17:30:50 -0700132 return true;
Jeff Thompson3c2ab012013-10-02 14:18:16 -0700133}
134
135bool
Alexander Afanasyevaf283d82014-01-03 13:23:34 -0800136Name::isPrefixOf(const Name& name) const
Jeff Thompsoncc35cd42013-08-20 12:23:14 -0700137{
Jeff Thompsone589c3f2013-10-12 17:30:50 -0700138 // This name is longer than the name we are checking it against.
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800139 if (size() > name.size())
Jeff Thompson3c2ab012013-10-02 14:18:16 -0700140 return false;
Jeff Thompsoncc35cd42013-08-20 12:23:14 -0700141
Jeff Thompsone589c3f2013-10-12 17:30:50 -0700142 // Check if at least one of given components doesn't match.
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800143 for (size_t i = 0; i < size(); ++i) {
144 if (at(i) != name.at(i))
Jeff Thompsoncc35cd42013-08-20 12:23:14 -0700145 return false;
146 }
147
Jeff Thompsone589c3f2013-10-12 17:30:50 -0700148 return true;
Jeff Thompsoncc35cd42013-08-20 12:23:14 -0700149}
150
Jeff Thompsonec7789a2013-08-21 11:08:36 -0700151
Jeff Thompsonafc45a92014-01-15 12:42:45 -0800152int
153Name::compare(const Name& other) const
Jeff Thompson82568ad2013-12-17 15:17:40 -0800154{
Jeff Thompsonafc45a92014-01-15 12:42:45 -0800155 for (size_t i = 0; i < size() && i < other.size(); ++i) {
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800156 int comparison = at(i).compare(other.at(i));
Jeff Thompsonafc45a92014-01-15 12:42:45 -0800157 if (comparison == 0)
Jeff Thompson82568ad2013-12-17 15:17:40 -0800158 // The components at this index are equal, so check the next components.
159 continue;
160
161 // Otherwise, the result is based on the components at this index.
Jeff Thompsonafc45a92014-01-15 12:42:45 -0800162 return comparison;
Jeff Thompson82568ad2013-12-17 15:17:40 -0800163 }
164
Jeff Thompsonafc45a92014-01-15 12:42:45 -0800165 // The components up to min(this.size(), other.size()) are equal, so the shorter name is less.
166 if (size() < other.size())
167 return -1;
168 else if (size() > other.size())
169 return 1;
170 else
171 return 0;
Jeff Thompson82568ad2013-12-17 15:17:40 -0800172}
173
Alexander Afanasyevaf283d82014-01-03 13:23:34 -0800174std::ostream&
175operator << (std::ostream& os, const Name& name)
176{
177 if (name.empty())
178 {
179 os << "/";
180 }
181 else
182 {
183 for (Name::const_iterator i = name.begin(); i != name.end(); i++) {
184 os << "/";
185 i->toEscapedString(os);
186 }
187 }
188
189 return os;
190}
Jeff Thompson82568ad2013-12-17 15:17:40 -0800191
Wentao Shang77949212014-02-01 23:42:24 -0800192} // namespace ndn