blob: fed4bab4a9f5ca5992200a0f164255ad8ebc95d7 [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{
26 try
27 {
28 Uri::fromEscaped (uri.begin (), uri.end (), back_inserter (*this));
29 }
30 catch (error::Uri &err)
31 {
32 // re-throwing different exception
33 BOOST_THROW_EXCEPTION (error::name::Component ()
34 << error::msg (uri)
35 << error::pos (error::get_pos (err)));
36 }
37}
38
39Component::Component (std::string::const_iterator begin, std::string::const_iterator end)
40{
41 try
42 {
43 Uri::fromEscaped (begin, end, back_inserter (*this));
44 }
45 catch (error::Uri &err)
46 {
47 // re-throwing different exception
48 BOOST_THROW_EXCEPTION (error::name::Component ()
49 << error::msg (std::string (begin, end))
50 << error::pos (error::get_pos (err)));
51 }
52}
53
54Component::Component (const void *buf, size_t length)
55{
56 copy (static_cast<const char*> (buf),
57 static_cast<const char*> (buf)+length,
58 back_inserter (*this));
59}
60
61int
62Component::compare (const Component &other) const
63{
64 if (size () < other.size ())
65 return -1;
66
67 if (size () > other.size ())
68 return +1;
69
70 // now we know that sizes are equal
71
72 std::pair<const_iterator, const_iterator> diff = mismatch (begin (), end (), other.begin ());
73 if (diff.first == end ()) // components are actually equal
74 return 0;
75
76 return (std::lexicographical_compare (diff.first, end (), diff.second, other.end ())) ? -1 : +1;
77}
78
79Component
80Component::fromNumber (uint64_t number)
81{
82 Component comp;
83 while (number > 0)
84 {
85 comp.push_back (static_cast<unsigned char> (number & 0xFF));
86 number >>= 8;
87 }
88 std::reverse (comp.begin (), comp.end ());
89 return comp;
90}
91
92Component
93Component::fromNumberWithMarker (uint64_t number, unsigned char marker)
94{
95 Component comp;
96 comp.push_back (marker);
97
98 while (number > 0)
99 {
100 comp.push_back (static_cast<unsigned char> (number & 0xFF));
101 number >>= 8;
102 }
103
104 std::reverse (comp.begin () + 1, comp.end ());
105 return comp;
106}
107
108std::string
109Component::toBlob () const
110{
111 return std::string (begin (), end ());
112}
113
114void
115Component::toBlob (std::ostream &os) const
116{
117 os.write (buf (), size ());
118}
119
120std::string
121Component::toUri () const
122{
123 std::ostringstream os;
124 toUri (os);
125 return os.str ();
126}
127
128void
129Component::toUri (std::ostream &os) const
130{
131 Uri::toEscaped (begin (), end (), std::ostream_iterator<char> (os));
132}
133
134uint64_t
135Component::toNumber () const
136{
137 uint64_t ret = 0;
138 for (const_iterator i = begin (); i != end (); i++)
139 {
140 ret <<= 8;
141 ret |= static_cast<unsigned char> (*i);
142 }
143 return ret;
144}
145
146uint64_t
147Component::toNumberWithMarker (unsigned char marker) const
148{
149 if (empty () ||
150 static_cast<unsigned char> (*(begin ())) != marker)
151 {
152 BOOST_THROW_EXCEPTION (error::name::Component ()
153 << error::msg ("Name component does not have required marker [" + toUri () + "]"));
154 }
155
156 uint64_t ret = 0;
157 for (const_iterator i = begin () + 1; i != end (); i++)
158 {
159 ret <<= 8;
160 ret |= static_cast<unsigned char> (*i);
161 }
162 return ret;
163}
164
165} // name
166
167NDN_NAMESPACE_END