blob: 084d6be4e850ccc54d6f2d1229c61054014c0ae9 [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
11#include "name-component.h"
12
13#include "detail/error.h"
14#include "detail/uri.h"
15
16NDN_NAMESPACE_BEGIN
17
18namespace name {
19
20Component::Component ()
21{
22}
23
24Component::Component (const std::string &uri)
25{
Alexander Afanasyevf23a7b62013-07-17 13:22:25 -070026 copy (uri.begin (), uri.end (), std::back_inserter (*this));
Alexander Afanasyev157c9e62013-07-16 20:58:04 -070027}
28
29Component::Component (std::string::const_iterator begin, std::string::const_iterator end)
30{
Alexander Afanasyevf23a7b62013-07-17 13:22:25 -070031 copy (begin, end, std::back_inserter (*this));
Alexander Afanasyev157c9e62013-07-16 20:58:04 -070032}
33
34Component::Component (const void *buf, size_t length)
35{
36 copy (static_cast<const char*> (buf),
37 static_cast<const char*> (buf)+length,
Alexander Afanasyevf23a7b62013-07-17 13:22:25 -070038 std::back_inserter (*this));
Alexander Afanasyev157c9e62013-07-16 20:58:04 -070039}
40
41Component &
42Component::fromUri (const std::string &uri)
43{
Alexander Afanasyev92136012013-07-16 20:36:30 -070044 try
45 {
Alexander Afanasyevf23a7b62013-07-17 13:22:25 -070046 Uri::fromEscaped (uri.begin (), uri.end (), std::back_inserter (*this));
Alexander Afanasyev92136012013-07-16 20:36:30 -070047 }
48 catch (error::Uri &err)
49 {
50 // re-throwing different exception
51 BOOST_THROW_EXCEPTION (error::name::Component ()
52 << error::msg (uri)
53 << error::pos (error::get_pos (err)));
54 }
Alexander Afanasyev157c9e62013-07-16 20:58:04 -070055
56 return *this;
Alexander Afanasyev92136012013-07-16 20:36:30 -070057}
58
Alexander Afanasyev157c9e62013-07-16 20:58:04 -070059Component &
60Component::fromUri (std::string::const_iterator begin, std::string::const_iterator end)
Alexander Afanasyev92136012013-07-16 20:36:30 -070061{
62 try
63 {
Alexander Afanasyevf23a7b62013-07-17 13:22:25 -070064 Uri::fromEscaped (begin, end, std::back_inserter (*this));
Alexander Afanasyev92136012013-07-16 20:36:30 -070065 }
66 catch (error::Uri &err)
67 {
68 // re-throwing different exception
69 BOOST_THROW_EXCEPTION (error::name::Component ()
70 << error::msg (std::string (begin, end))
71 << error::pos (error::get_pos (err)));
72 }
Alexander Afanasyev157c9e62013-07-16 20:58:04 -070073 return *this;
Alexander Afanasyev92136012013-07-16 20:36:30 -070074}
75
76int
77Component::compare (const Component &other) const
78{
79 if (size () < other.size ())
80 return -1;
81
82 if (size () > other.size ())
83 return +1;
84
85 // now we know that sizes are equal
86
87 std::pair<const_iterator, const_iterator> diff = mismatch (begin (), end (), other.begin ());
88 if (diff.first == end ()) // components are actually equal
89 return 0;
90
91 return (std::lexicographical_compare (diff.first, end (), diff.second, other.end ())) ? -1 : +1;
92}
93
Alexander Afanasyev157c9e62013-07-16 20:58:04 -070094Component &
Alexander Afanasyev92136012013-07-16 20:36:30 -070095Component::fromNumber (uint64_t number)
96{
Alexander Afanasyev92136012013-07-16 20:36:30 -070097 while (number > 0)
98 {
Alexander Afanasyev157c9e62013-07-16 20:58:04 -070099 this->push_back (static_cast<unsigned char> (number & 0xFF));
Alexander Afanasyev92136012013-07-16 20:36:30 -0700100 number >>= 8;
101 }
Alexander Afanasyev157c9e62013-07-16 20:58:04 -0700102 std::reverse (this->begin (), this->end ());
103 return *this;
Alexander Afanasyev92136012013-07-16 20:36:30 -0700104}
105
Alexander Afanasyev157c9e62013-07-16 20:58:04 -0700106Component &
Alexander Afanasyev92136012013-07-16 20:36:30 -0700107Component::fromNumberWithMarker (uint64_t number, unsigned char marker)
108{
Alexander Afanasyev157c9e62013-07-16 20:58:04 -0700109 this->push_back (marker);
Alexander Afanasyev92136012013-07-16 20:36:30 -0700110
111 while (number > 0)
112 {
Alexander Afanasyev157c9e62013-07-16 20:58:04 -0700113 this->push_back (static_cast<unsigned char> (number & 0xFF));
Alexander Afanasyev92136012013-07-16 20:36:30 -0700114 number >>= 8;
115 }
116
Alexander Afanasyev157c9e62013-07-16 20:58:04 -0700117 std::reverse (this->begin () + 1, this->end ());
118 return *this;
Alexander Afanasyev92136012013-07-16 20:36:30 -0700119}
120
121std::string
122Component::toBlob () const
123{
124 return std::string (begin (), end ());
125}
126
127void
128Component::toBlob (std::ostream &os) const
129{
130 os.write (buf (), size ());
131}
132
133std::string
134Component::toUri () const
135{
136 std::ostringstream os;
137 toUri (os);
138 return os.str ();
139}
140
141void
142Component::toUri (std::ostream &os) const
143{
144 Uri::toEscaped (begin (), end (), std::ostream_iterator<char> (os));
145}
146
147uint64_t
148Component::toNumber () const
149{
150 uint64_t ret = 0;
151 for (const_iterator i = begin (); i != end (); i++)
152 {
153 ret <<= 8;
154 ret |= static_cast<unsigned char> (*i);
155 }
156 return ret;
157}
158
159uint64_t
160Component::toNumberWithMarker (unsigned char marker) const
161{
162 if (empty () ||
163 static_cast<unsigned char> (*(begin ())) != marker)
164 {
165 BOOST_THROW_EXCEPTION (error::name::Component ()
166 << error::msg ("Name component does not have required marker [" + toUri () + "]"));
167 }
168
169 uint64_t ret = 0;
170 for (const_iterator i = begin () + 1; i != end (); i++)
171 {
172 ret <<= 8;
173 ret |= static_cast<unsigned char> (*i);
174 }
175 return ret;
176}
177
178} // name
179
180NDN_NAMESPACE_END