blob: 69b458b0b8963fe1f2e0a4f83644db3d175a06aa [file] [log] [blame]
Alexander Afanasyevc169a812014-05-20 20:37:29 -04001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Jeff Thompson5cae5e52013-07-10 19:41:20 -07002/**
Alexander Afanasyevc169a812014-05-20 20:37:29 -04003 * Copyright (c) 2013-2014 Regents of the University of California.
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07004 *
5 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07006 *
Alexander Afanasyevc169a812014-05-20 20:37:29 -04007 * ndn-cxx library is free software: you can redistribute it and/or modify it under the
8 * terms of the GNU Lesser General Public License as published by the Free Software
9 * Foundation, either version 3 of the License, or (at your option) any later version.
10 *
11 * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
14 *
15 * You should have received copies of the GNU General Public License and GNU Lesser
16 * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
17 * <http://www.gnu.org/licenses/>.
18 *
19 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
Jeff Thompson5cae5e52013-07-10 19:41:20 -070020 */
21
Jeff Thompson71b2f872013-12-17 12:03:17 -080022#ifndef NDN_KEY_LOCATOR_HPP
23#define NDN_KEY_LOCATOR_HPP
Jeff Thompson5cae5e52013-07-10 19:41:20 -070024
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080025#include "encoding/block.hpp"
Jeff Thompson2e6269c2013-08-22 10:36:00 -070026#include "name.hpp"
Jeff Thompson5cae5e52013-07-10 19:41:20 -070027
28namespace ndn {
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -080029
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -070030class KeyLocator
31{
Jeff Thompson5cae5e52013-07-10 19:41:20 -070032public:
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070033 class Error : public std::runtime_error
34 {
35 public:
36 explicit
37 Error(const std::string& what)
38 : std::runtime_error(what)
39 {
40 }
41 };
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070042
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -080043 enum {
Alexander Afanasyev9cae6682014-02-19 14:18:56 -080044 KeyLocator_None = 65535, // just an arbitrarily large number (used only internally)
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080045 KeyLocator_Name = 0,
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070046
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080047 KeyLocator_Unknown = 255
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -080048 };
Alexander Afanasyevfa13f8e2014-01-03 15:19:07 -080049
Jeff Thompson5cae5e52013-07-10 19:41:20 -070050 KeyLocator()
Alexander Afanasyev809805d2014-02-17 17:20:33 -080051 : m_type(KeyLocator_None)
Jeff Thompson5cae5e52013-07-10 19:41:20 -070052 {
Jeff Thompson5cae5e52013-07-10 19:41:20 -070053 }
Jeff Thompson5cae5e52013-07-10 19:41:20 -070054
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070055 KeyLocator(const Name& name)
56 {
57 setName(name);
58 }
59
60 /**
61 * @brief Create from wire encoding
62 */
63 explicit
64 KeyLocator(const Block& wire)
65 {
66 wireDecode(wire);
67 }
Alexander Afanasyevfa13f8e2014-01-03 15:19:07 -080068
Alexander Afanasyev809805d2014-02-17 17:20:33 -080069 ///////////////////////////////////////////////////////////////////////////////
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070070
Alexander Afanasyev809805d2014-02-17 17:20:33 -080071 template<bool T>
72 size_t
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070073 wireEncode(EncodingImpl<T>& block) const;
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080074
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070075 const Block&
Alexander Afanasyev809805d2014-02-17 17:20:33 -080076 wireEncode() const;
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070077
Alexander Afanasyev809805d2014-02-17 17:20:33 -080078 void
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070079 wireDecode(const Block& wire);
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070080
Alexander Afanasyev809805d2014-02-17 17:20:33 -080081 ///////////////////////////////////////////////////////////////////////////////
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070082
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070083 bool
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -080084 empty() const
85 {
Alexander Afanasyev809805d2014-02-17 17:20:33 -080086 return m_type == KeyLocator_None;
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -080087 }
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070088
89 uint32_t
Alexander Afanasyev809805d2014-02-17 17:20:33 -080090 getType() const { return m_type; }
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070091
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -080092 ////////////////////////////////////////////////////////
93 // Helper methods for different types of key locators
94 //
95 // For now only Name type is actually supported
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070096
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070097 const Name&
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080098 getName() const;
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -080099
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700100 void
101 setName(const Name& name);
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700102
103public: // EqualityComparable concept
104 bool
105 operator==(const KeyLocator& other) const;
106
107 bool
108 operator!=(const KeyLocator& other) const;
109
Jeff Thompson5cae5e52013-07-10 19:41:20 -0700110private:
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800111 uint32_t m_type;
112 Name m_name;
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700113
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800114 mutable Block m_wire;
Jeff Thompson5cae5e52013-07-10 19:41:20 -0700115};
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -0800116
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800117template<bool T>
118inline size_t
119KeyLocator::wireEncode(EncodingImpl<T>& block) const
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800120{
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800121 // KeyLocator ::= KEY-LOCATOR-TYPE TLV-LENGTH KeyLocatorValue
Alexander Afanasyeve9a66e52014-01-17 16:07:17 -0800122
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800123 // KeyLocatorValue ::= Name |
124 // KeyLocatorDigest | (not supported yet)
125 // ...
Alexander Afanasyeve9a66e52014-01-17 16:07:17 -0800126
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800127 // KeyLocatorDigest ::= KEY-LOCATOR-DIGEST-TYPE TLV-LENGTH BYTE+
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700128
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700129 size_t totalLength = 0;
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800130
131 switch (m_type) {
Alexander Afanasyeve9a66e52014-01-17 16:07:17 -0800132 case KeyLocator_None:
Alexander Afanasyeve9a66e52014-01-17 16:07:17 -0800133 break;
134 case KeyLocator_Name:
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700135 totalLength += m_name.wireEncode(block);
Alexander Afanasyeve9a66e52014-01-17 16:07:17 -0800136 break;
137 default:
138 throw Error("Unsupported KeyLocator type");
139 }
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800140
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700141 totalLength += block.prependVarNumber(totalLength);
142 totalLength += block.prependVarNumber(Tlv::KeyLocator);
143 return totalLength;
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800144}
145
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700146inline const Block&
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800147KeyLocator::wireEncode() const
148{
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700149 if (m_wire.hasWire())
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800150 return m_wire;
151
152 EncodingEstimator estimator;
153 size_t estimatedSize = wireEncode(estimator);
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700154
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800155 EncodingBuffer buffer(estimatedSize, 0);
156 wireEncode(buffer);
157
158 m_wire = buffer.block();
159 return m_wire;
Jeff Thompson5cae5e52013-07-10 19:41:20 -0700160}
161
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700162inline void
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700163KeyLocator::wireDecode(const Block& value)
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800164{
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800165 if (value.type() != Tlv::KeyLocator)
166 throw Error("Unexpected TLV type during KeyLocator decoding");
167
168 m_wire = value;
169 m_wire.parse();
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700170
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800171 if (!m_wire.elements().empty() && m_wire.elements_begin()->type() == Tlv::Name)
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800172 {
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800173 m_type = KeyLocator_Name;
174 m_name.wireDecode(*m_wire.elements_begin());
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800175 }
176 else
177 {
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800178 m_type = KeyLocator_Unknown;
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800179 }
180}
181
182inline const Name&
183KeyLocator::getName() const
184{
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800185 if (m_type != KeyLocator_Name)
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800186 throw Error("Requested Name, but KeyLocator is not of the Name type");
187
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800188 return m_name;
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800189}
190
191inline void
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700192KeyLocator::setName(const Name& name)
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800193{
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700194 m_wire.reset();
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800195 m_type = KeyLocator_Name;
196 m_name = name;
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800197}
198
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700199inline bool
200KeyLocator::operator==(const KeyLocator& other) const
201{
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700202 return wireEncode() == other.wireEncode();
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700203}
204
205inline bool
206KeyLocator::operator!=(const KeyLocator& other) const
207{
208 return !this->operator==(other);
209}
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800210
211} // namespace ndn
212
Jeff Thompson5cae5e52013-07-10 19:41:20 -0700213#endif