blob: 4f4e2532167682df3de2e7275f9f7b40ff676f94 [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"
Alexander Afanasyev46992422013-08-03 17:21:15 -070014#elif __GNUC__
15#pragma GCC diagnostic ignored "-Wreorder"
Alexander Afanasyev3898e1b2013-07-27 12:03:17 -070016#endif
17
Alexander Afanasyev92136012013-07-16 20:36:30 -070018#include "name-component.h"
19
20#include "detail/error.h"
21#include "detail/uri.h"
22
23NDN_NAMESPACE_BEGIN
24
25namespace name {
26
27Component::Component ()
28{
29}
30
31Component::Component (const std::string &uri)
32{
Alexander Afanasyevf23a7b62013-07-17 13:22:25 -070033 copy (uri.begin (), uri.end (), std::back_inserter (*this));
Alexander Afanasyev157c9e62013-07-16 20:58:04 -070034}
35
36Component::Component (std::string::const_iterator begin, std::string::const_iterator end)
37{
Alexander Afanasyevf23a7b62013-07-17 13:22:25 -070038 copy (begin, end, std::back_inserter (*this));
Alexander Afanasyev157c9e62013-07-16 20:58:04 -070039}
40
41Component::Component (const void *buf, size_t length)
42{
43 copy (static_cast<const char*> (buf),
44 static_cast<const char*> (buf)+length,
Alexander Afanasyevf23a7b62013-07-17 13:22:25 -070045 std::back_inserter (*this));
Alexander Afanasyev157c9e62013-07-16 20:58:04 -070046}
47
48Component &
49Component::fromUri (const std::string &uri)
50{
Alexander Afanasyev92136012013-07-16 20:36:30 -070051 try
52 {
Alexander Afanasyevf23a7b62013-07-17 13:22:25 -070053 Uri::fromEscaped (uri.begin (), uri.end (), std::back_inserter (*this));
Alexander Afanasyev92136012013-07-16 20:36:30 -070054 }
55 catch (error::Uri &err)
56 {
57 // re-throwing different exception
58 BOOST_THROW_EXCEPTION (error::name::Component ()
59 << error::msg (uri)
60 << error::pos (error::get_pos (err)));
61 }
Alexander Afanasyev157c9e62013-07-16 20:58:04 -070062
63 return *this;
Alexander Afanasyev92136012013-07-16 20:36:30 -070064}
65
Alexander Afanasyev157c9e62013-07-16 20:58:04 -070066Component &
67Component::fromUri (std::string::const_iterator begin, std::string::const_iterator end)
Alexander Afanasyev92136012013-07-16 20:36:30 -070068{
69 try
70 {
Alexander Afanasyevf23a7b62013-07-17 13:22:25 -070071 Uri::fromEscaped (begin, end, std::back_inserter (*this));
Alexander Afanasyev92136012013-07-16 20:36:30 -070072 }
73 catch (error::Uri &err)
74 {
75 // re-throwing different exception
76 BOOST_THROW_EXCEPTION (error::name::Component ()
77 << error::msg (std::string (begin, end))
78 << error::pos (error::get_pos (err)));
79 }
Alexander Afanasyev157c9e62013-07-16 20:58:04 -070080 return *this;
Alexander Afanasyev92136012013-07-16 20:36:30 -070081}
82
83int
84Component::compare (const Component &other) const
85{
86 if (size () < other.size ())
87 return -1;
88
89 if (size () > other.size ())
90 return +1;
91
92 // now we know that sizes are equal
93
94 std::pair<const_iterator, const_iterator> diff = mismatch (begin (), end (), other.begin ());
95 if (diff.first == end ()) // components are actually equal
96 return 0;
97
98 return (std::lexicographical_compare (diff.first, end (), diff.second, other.end ())) ? -1 : +1;
99}
100
Alexander Afanasyev157c9e62013-07-16 20:58:04 -0700101Component &
Alexander Afanasyev92136012013-07-16 20:36:30 -0700102Component::fromNumber (uint64_t number)
103{
Alexander Afanasyev92136012013-07-16 20:36:30 -0700104 while (number > 0)
105 {
Alexander Afanasyev157c9e62013-07-16 20:58:04 -0700106 this->push_back (static_cast<unsigned char> (number & 0xFF));
Alexander Afanasyev92136012013-07-16 20:36:30 -0700107 number >>= 8;
108 }
Alexander Afanasyev157c9e62013-07-16 20:58:04 -0700109 std::reverse (this->begin (), this->end ());
110 return *this;
Alexander Afanasyev92136012013-07-16 20:36:30 -0700111}
112
Alexander Afanasyev157c9e62013-07-16 20:58:04 -0700113Component &
Alexander Afanasyev92136012013-07-16 20:36:30 -0700114Component::fromNumberWithMarker (uint64_t number, unsigned char marker)
115{
Alexander Afanasyev157c9e62013-07-16 20:58:04 -0700116 this->push_back (marker);
Alexander Afanasyev92136012013-07-16 20:36:30 -0700117
118 while (number > 0)
119 {
Alexander Afanasyev157c9e62013-07-16 20:58:04 -0700120 this->push_back (static_cast<unsigned char> (number & 0xFF));
Alexander Afanasyev92136012013-07-16 20:36:30 -0700121 number >>= 8;
122 }
123
Alexander Afanasyev157c9e62013-07-16 20:58:04 -0700124 std::reverse (this->begin () + 1, this->end ());
125 return *this;
Alexander Afanasyev92136012013-07-16 20:36:30 -0700126}
127
128std::string
129Component::toBlob () const
130{
131 return std::string (begin (), end ());
132}
133
134void
135Component::toBlob (std::ostream &os) const
136{
137 os.write (buf (), size ());
138}
139
140std::string
141Component::toUri () const
142{
143 std::ostringstream os;
144 toUri (os);
145 return os.str ();
146}
147
148void
149Component::toUri (std::ostream &os) const
150{
151 Uri::toEscaped (begin (), end (), std::ostream_iterator<char> (os));
152}
153
154uint64_t
155Component::toNumber () const
156{
157 uint64_t ret = 0;
158 for (const_iterator i = begin (); i != end (); i++)
159 {
160 ret <<= 8;
161 ret |= static_cast<unsigned char> (*i);
162 }
163 return ret;
164}
165
166uint64_t
167Component::toNumberWithMarker (unsigned char marker) const
168{
169 if (empty () ||
170 static_cast<unsigned char> (*(begin ())) != marker)
171 {
172 BOOST_THROW_EXCEPTION (error::name::Component ()
173 << error::msg ("Name component does not have required marker [" + toUri () + "]"));
174 }
175
176 uint64_t ret = 0;
177 for (const_iterator i = begin () + 1; i != end (); i++)
178 {
179 ret <<= 8;
180 ret |= static_cast<unsigned char> (*i);
181 }
182 return ret;
183}
184
185} // name
186
187NDN_NAMESPACE_END