blob: a86275d538449e54d4ddd1637e531a25abc48458 [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"
Alexander Afanasyev15f67312014-07-22 15:11:09 -070026#include "encoding/encoding-buffer.hpp"
27
Jeff Thompson2e6269c2013-08-22 10:36:00 -070028#include "name.hpp"
Jeff Thompson5cae5e52013-07-10 19:41:20 -070029
30namespace ndn {
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -080031
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -070032class KeyLocator
33{
Jeff Thompson5cae5e52013-07-10 19:41:20 -070034public:
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070035 class Error : public std::runtime_error
36 {
37 public:
38 explicit
39 Error(const std::string& what)
40 : std::runtime_error(what)
41 {
42 }
43 };
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070044
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -080045 enum {
Alexander Afanasyev9cae6682014-02-19 14:18:56 -080046 KeyLocator_None = 65535, // just an arbitrarily large number (used only internally)
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080047 KeyLocator_Name = 0,
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070048
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080049 KeyLocator_Unknown = 255
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -080050 };
Alexander Afanasyevfa13f8e2014-01-03 15:19:07 -080051
Jeff Thompson5cae5e52013-07-10 19:41:20 -070052 KeyLocator()
Alexander Afanasyev809805d2014-02-17 17:20:33 -080053 : m_type(KeyLocator_None)
Jeff Thompson5cae5e52013-07-10 19:41:20 -070054 {
Jeff Thompson5cae5e52013-07-10 19:41:20 -070055 }
Jeff Thompson5cae5e52013-07-10 19:41:20 -070056
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070057 KeyLocator(const Name& name)
58 {
59 setName(name);
60 }
61
62 /**
63 * @brief Create from wire encoding
64 */
65 explicit
66 KeyLocator(const Block& wire)
67 {
68 wireDecode(wire);
69 }
Alexander Afanasyevfa13f8e2014-01-03 15:19:07 -080070
Alexander Afanasyev809805d2014-02-17 17:20:33 -080071 ///////////////////////////////////////////////////////////////////////////////
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070072
Alexander Afanasyev809805d2014-02-17 17:20:33 -080073 template<bool T>
74 size_t
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070075 wireEncode(EncodingImpl<T>& block) const;
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080076
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070077 const Block&
Alexander Afanasyev809805d2014-02-17 17:20:33 -080078 wireEncode() const;
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070079
Alexander Afanasyev809805d2014-02-17 17:20:33 -080080 void
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070081 wireDecode(const Block& wire);
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070082
Alexander Afanasyev809805d2014-02-17 17:20:33 -080083 ///////////////////////////////////////////////////////////////////////////////
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070084
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070085 bool
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -080086 empty() const
87 {
Alexander Afanasyev809805d2014-02-17 17:20:33 -080088 return m_type == KeyLocator_None;
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -080089 }
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070090
91 uint32_t
Alexander Afanasyev809805d2014-02-17 17:20:33 -080092 getType() const { return m_type; }
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070093
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -080094 ////////////////////////////////////////////////////////
95 // Helper methods for different types of key locators
96 //
97 // For now only Name type is actually supported
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070098
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070099 const Name&
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800100 getName() const;
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -0800101
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700102 void
103 setName(const Name& name);
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700104
105public: // EqualityComparable concept
106 bool
107 operator==(const KeyLocator& other) const;
108
109 bool
110 operator!=(const KeyLocator& other) const;
111
Jeff Thompson5cae5e52013-07-10 19:41:20 -0700112private:
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800113 uint32_t m_type;
114 Name m_name;
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700115
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800116 mutable Block m_wire;
Jeff Thompson5cae5e52013-07-10 19:41:20 -0700117};
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -0800118
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800119template<bool T>
120inline size_t
121KeyLocator::wireEncode(EncodingImpl<T>& block) const
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800122{
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800123 // KeyLocator ::= KEY-LOCATOR-TYPE TLV-LENGTH KeyLocatorValue
Alexander Afanasyeve9a66e52014-01-17 16:07:17 -0800124
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800125 // KeyLocatorValue ::= Name |
126 // KeyLocatorDigest | (not supported yet)
127 // ...
Alexander Afanasyeve9a66e52014-01-17 16:07:17 -0800128
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800129 // KeyLocatorDigest ::= KEY-LOCATOR-DIGEST-TYPE TLV-LENGTH BYTE+
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700130
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700131 size_t totalLength = 0;
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800132
133 switch (m_type) {
Alexander Afanasyeve9a66e52014-01-17 16:07:17 -0800134 case KeyLocator_None:
Alexander Afanasyeve9a66e52014-01-17 16:07:17 -0800135 break;
136 case KeyLocator_Name:
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700137 totalLength += m_name.wireEncode(block);
Alexander Afanasyeve9a66e52014-01-17 16:07:17 -0800138 break;
139 default:
140 throw Error("Unsupported KeyLocator type");
141 }
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800142
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700143 totalLength += block.prependVarNumber(totalLength);
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600144 totalLength += block.prependVarNumber(tlv::KeyLocator);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700145 return totalLength;
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800146}
147
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700148inline const Block&
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800149KeyLocator::wireEncode() const
150{
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700151 if (m_wire.hasWire())
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800152 return m_wire;
153
154 EncodingEstimator estimator;
155 size_t estimatedSize = wireEncode(estimator);
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700156
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800157 EncodingBuffer buffer(estimatedSize, 0);
158 wireEncode(buffer);
159
160 m_wire = buffer.block();
161 return m_wire;
Jeff Thompson5cae5e52013-07-10 19:41:20 -0700162}
163
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700164inline void
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700165KeyLocator::wireDecode(const Block& value)
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800166{
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600167 if (value.type() != tlv::KeyLocator)
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800168 throw Error("Unexpected TLV type during KeyLocator decoding");
169
170 m_wire = value;
171 m_wire.parse();
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700172
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600173 if (!m_wire.elements().empty() && m_wire.elements_begin()->type() == tlv::Name)
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800174 {
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800175 m_type = KeyLocator_Name;
176 m_name.wireDecode(*m_wire.elements_begin());
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800177 }
178 else
179 {
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800180 m_type = KeyLocator_Unknown;
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800181 }
182}
183
184inline const Name&
185KeyLocator::getName() const
186{
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800187 if (m_type != KeyLocator_Name)
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800188 throw Error("Requested Name, but KeyLocator is not of the Name type");
189
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800190 return m_name;
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800191}
192
193inline void
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700194KeyLocator::setName(const Name& name)
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800195{
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700196 m_wire.reset();
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800197 m_type = KeyLocator_Name;
198 m_name = name;
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800199}
200
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700201inline bool
202KeyLocator::operator==(const KeyLocator& other) const
203{
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700204 return wireEncode() == other.wireEncode();
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700205}
206
207inline bool
208KeyLocator::operator!=(const KeyLocator& other) const
209{
210 return !this->operator==(other);
211}
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800212
213} // namespace ndn
214
Jeff Thompson5cae5e52013-07-10 19:41:20 -0700215#endif