blob: 20bdb6a669564e2069bf9a8146e3e4d4ba604a27 [file] [log] [blame]
Alexander Afanasyev92136012013-07-16 20:36:30 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2/*
3 * Copyright (c) 2013, Regents of the University of California
4 * Alexander Afanasyev
5 *
6 * BSD license, See the LICENSE file for more information
7 *
8 * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
9 */
10
Alexander Afanasyev3898e1b2013-07-27 12:03:17 -070011#if __clang__
12#pragma clang diagnostic push
13#pragma clang diagnostic ignored "-Wreorder"
14#endif
15
Alexander Afanasyev92136012013-07-16 20:36:30 -070016#include "name-component.h"
17
18#include "detail/error.h"
19#include "detail/uri.h"
20
21NDN_NAMESPACE_BEGIN
22
23namespace name {
24
25Component::Component ()
26{
27}
28
29Component::Component (const std::string &uri)
30{
Alexander Afanasyevf23a7b62013-07-17 13:22:25 -070031 copy (uri.begin (), uri.end (), std::back_inserter (*this));
Alexander Afanasyev157c9e62013-07-16 20:58:04 -070032}
33
34Component::Component (std::string::const_iterator begin, std::string::const_iterator end)
35{
Alexander Afanasyevf23a7b62013-07-17 13:22:25 -070036 copy (begin, end, std::back_inserter (*this));
Alexander Afanasyev157c9e62013-07-16 20:58:04 -070037}
38
39Component::Component (const void *buf, size_t length)
40{
41 copy (static_cast<const char*> (buf),
42 static_cast<const char*> (buf)+length,
Alexander Afanasyevf23a7b62013-07-17 13:22:25 -070043 std::back_inserter (*this));
Alexander Afanasyev157c9e62013-07-16 20:58:04 -070044}
45
46Component &
47Component::fromUri (const std::string &uri)
48{
Alexander Afanasyev92136012013-07-16 20:36:30 -070049 try
50 {
Alexander Afanasyevf23a7b62013-07-17 13:22:25 -070051 Uri::fromEscaped (uri.begin (), uri.end (), std::back_inserter (*this));
Alexander Afanasyev92136012013-07-16 20:36:30 -070052 }
53 catch (error::Uri &err)
54 {
55 // re-throwing different exception
56 BOOST_THROW_EXCEPTION (error::name::Component ()
57 << error::msg (uri)
58 << error::pos (error::get_pos (err)));
59 }
Alexander Afanasyev157c9e62013-07-16 20:58:04 -070060
61 return *this;
Alexander Afanasyev92136012013-07-16 20:36:30 -070062}
63
Alexander Afanasyev157c9e62013-07-16 20:58:04 -070064Component &
65Component::fromUri (std::string::const_iterator begin, std::string::const_iterator end)
Alexander Afanasyev92136012013-07-16 20:36:30 -070066{
67 try
68 {
Alexander Afanasyevf23a7b62013-07-17 13:22:25 -070069 Uri::fromEscaped (begin, end, std::back_inserter (*this));
Alexander Afanasyev92136012013-07-16 20:36:30 -070070 }
71 catch (error::Uri &err)
72 {
73 // re-throwing different exception
74 BOOST_THROW_EXCEPTION (error::name::Component ()
75 << error::msg (std::string (begin, end))
76 << error::pos (error::get_pos (err)));
77 }
Alexander Afanasyev157c9e62013-07-16 20:58:04 -070078 return *this;
Alexander Afanasyev92136012013-07-16 20:36:30 -070079}
80
81int
82Component::compare (const Component &other) const
83{
84 if (size () < other.size ())
85 return -1;
86
87 if (size () > other.size ())
88 return +1;
89
90 // now we know that sizes are equal
91
92 std::pair<const_iterator, const_iterator> diff = mismatch (begin (), end (), other.begin ());
93 if (diff.first == end ()) // components are actually equal
94 return 0;
95
96 return (std::lexicographical_compare (diff.first, end (), diff.second, other.end ())) ? -1 : +1;
97}
98
Alexander Afanasyev157c9e62013-07-16 20:58:04 -070099Component &
Alexander Afanasyev92136012013-07-16 20:36:30 -0700100Component::fromNumber (uint64_t number)
101{
Alexander Afanasyev92136012013-07-16 20:36:30 -0700102 while (number > 0)
103 {
Alexander Afanasyev157c9e62013-07-16 20:58:04 -0700104 this->push_back (static_cast<unsigned char> (number & 0xFF));
Alexander Afanasyev92136012013-07-16 20:36:30 -0700105 number >>= 8;
106 }
Alexander Afanasyev157c9e62013-07-16 20:58:04 -0700107 std::reverse (this->begin (), this->end ());
108 return *this;
Alexander Afanasyev92136012013-07-16 20:36:30 -0700109}
110
Alexander Afanasyev157c9e62013-07-16 20:58:04 -0700111Component &
Alexander Afanasyev92136012013-07-16 20:36:30 -0700112Component::fromNumberWithMarker (uint64_t number, unsigned char marker)
113{
Alexander Afanasyev157c9e62013-07-16 20:58:04 -0700114 this->push_back (marker);
Alexander Afanasyev92136012013-07-16 20:36:30 -0700115
116 while (number > 0)
117 {
Alexander Afanasyev157c9e62013-07-16 20:58:04 -0700118 this->push_back (static_cast<unsigned char> (number & 0xFF));
Alexander Afanasyev92136012013-07-16 20:36:30 -0700119 number >>= 8;
120 }
121
Alexander Afanasyev157c9e62013-07-16 20:58:04 -0700122 std::reverse (this->begin () + 1, this->end ());
123 return *this;
Alexander Afanasyev92136012013-07-16 20:36:30 -0700124}
125
126std::string
127Component::toBlob () const
128{
129 return std::string (begin (), end ());
130}
131
132void
133Component::toBlob (std::ostream &os) const
134{
135 os.write (buf (), size ());
136}
137
138std::string
139Component::toUri () const
140{
141 std::ostringstream os;
142 toUri (os);
143 return os.str ();
144}
145
146void
147Component::toUri (std::ostream &os) const
148{
149 Uri::toEscaped (begin (), end (), std::ostream_iterator<char> (os));
150}
151
152uint64_t
153Component::toNumber () const
154{
155 uint64_t ret = 0;
156 for (const_iterator i = begin (); i != end (); i++)
157 {
158 ret <<= 8;
159 ret |= static_cast<unsigned char> (*i);
160 }
161 return ret;
162}
163
164uint64_t
165Component::toNumberWithMarker (unsigned char marker) const
166{
167 if (empty () ||
168 static_cast<unsigned char> (*(begin ())) != marker)
169 {
170 BOOST_THROW_EXCEPTION (error::name::Component ()
171 << error::msg ("Name component does not have required marker [" + toUri () + "]"));
172 }
173
174 uint64_t ret = 0;
175 for (const_iterator i = begin () + 1; i != end (); i++)
176 {
177 ret <<= 8;
178 ret |= static_cast<unsigned char> (*i);
179 }
180 return ret;
181}
182
183} // name
184
185NDN_NAMESPACE_END