blob: 1c714893b82c6292a17df08099a6804c9f396052 [file] [log] [blame]
Jeff Thompson25b4e612013-10-10 16:03:24 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
Jeff Thompson5cae5e52013-07-10 19:41:20 -07002/**
Jeff Thompson7687dc02013-09-13 11:54:07 -07003 * Copyright (C) 2013 Regents of the University of California.
4 * @author: Jeff Thompson <jefft0@remap.ucla.edu>
Jeff Thompson5cae5e52013-07-10 19:41:20 -07005 * See COPYING for copyright and distribution information.
6 */
7
Jeff Thompson71b2f872013-12-17 12:03:17 -08008#ifndef NDN_KEY_LOCATOR_HPP
9#define NDN_KEY_LOCATOR_HPP
Jeff Thompson5cae5e52013-07-10 19:41:20 -070010
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080011#include "encoding/block.hpp"
Jeff Thompson2e6269c2013-08-22 10:36:00 -070012#include "name.hpp"
Jeff Thompson5cae5e52013-07-10 19:41:20 -070013
14namespace ndn {
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -080015
Jeff Thompson5cae5e52013-07-10 19:41:20 -070016class KeyLocator {
17public:
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080018 struct Error : public std::runtime_error { Error(const std::string &what) : std::runtime_error(what) {} };
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070019
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -080020 enum {
Alexander Afanasyev9cae6682014-02-19 14:18:56 -080021 KeyLocator_None = 65535, // just an arbitrarily large number (used only internally)
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080022 KeyLocator_Name = 0,
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070023
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080024 KeyLocator_Unknown = 255
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -080025 };
Alexander Afanasyevfa13f8e2014-01-03 15:19:07 -080026
27 inline
Jeff Thompson5cae5e52013-07-10 19:41:20 -070028 KeyLocator()
Alexander Afanasyev809805d2014-02-17 17:20:33 -080029 : m_type(KeyLocator_None)
Jeff Thompson5cae5e52013-07-10 19:41:20 -070030 {
Jeff Thompson5cae5e52013-07-10 19:41:20 -070031 }
Jeff Thompson5cae5e52013-07-10 19:41:20 -070032
Alexander Afanasyevfa13f8e2014-01-03 15:19:07 -080033 inline
34 KeyLocator(const Name &name);
35
Alexander Afanasyev809805d2014-02-17 17:20:33 -080036 ///////////////////////////////////////////////////////////////////////////////
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070037
Alexander Afanasyev809805d2014-02-17 17:20:33 -080038 template<bool T>
39 size_t
40 wireEncode(EncodingImpl<T> &block) const;
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080041
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070042 const Block&
Alexander Afanasyev809805d2014-02-17 17:20:33 -080043 wireEncode() const;
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070044
Alexander Afanasyev809805d2014-02-17 17:20:33 -080045 void
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070046 wireDecode(const Block &wire);
47
Alexander Afanasyev809805d2014-02-17 17:20:33 -080048 ///////////////////////////////////////////////////////////////////////////////
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070049
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -080050 inline bool
51 empty() const
52 {
Alexander Afanasyev809805d2014-02-17 17:20:33 -080053 return m_type == KeyLocator_None;
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -080054 }
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070055
56 uint32_t
Alexander Afanasyev809805d2014-02-17 17:20:33 -080057 getType() const { return m_type; }
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070058
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -080059 ////////////////////////////////////////////////////////
60 // Helper methods for different types of key locators
61 //
62 // For now only Name type is actually supported
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070063
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080064 inline const Name&
65 getName() const;
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -080066
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080067 inline void
68 setName(const Name &name);
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070069
70public: // EqualityComparable concept
71 bool
72 operator==(const KeyLocator& other) const;
73
74 bool
75 operator!=(const KeyLocator& other) const;
76
Jeff Thompson5cae5e52013-07-10 19:41:20 -070077private:
Alexander Afanasyev809805d2014-02-17 17:20:33 -080078 uint32_t m_type;
79 Name m_name;
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070080
Alexander Afanasyev809805d2014-02-17 17:20:33 -080081 mutable Block m_wire;
Jeff Thompson5cae5e52013-07-10 19:41:20 -070082};
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -080083
Alexander Afanasyevfa13f8e2014-01-03 15:19:07 -080084inline
85KeyLocator::KeyLocator(const Name &name)
86{
87 setName(name);
88}
89
Alexander Afanasyev809805d2014-02-17 17:20:33 -080090template<bool T>
91inline size_t
92KeyLocator::wireEncode(EncodingImpl<T>& block) const
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080093{
Alexander Afanasyev809805d2014-02-17 17:20:33 -080094 // KeyLocator ::= KEY-LOCATOR-TYPE TLV-LENGTH KeyLocatorValue
Alexander Afanasyeve9a66e52014-01-17 16:07:17 -080095
Alexander Afanasyev809805d2014-02-17 17:20:33 -080096 // KeyLocatorValue ::= Name |
97 // KeyLocatorDigest | (not supported yet)
98 // ...
Alexander Afanasyeve9a66e52014-01-17 16:07:17 -080099
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800100 // KeyLocatorDigest ::= KEY-LOCATOR-DIGEST-TYPE TLV-LENGTH BYTE+
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700101
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800102 size_t total_len = 0;
103
104 switch (m_type) {
Alexander Afanasyeve9a66e52014-01-17 16:07:17 -0800105 case KeyLocator_None:
Alexander Afanasyeve9a66e52014-01-17 16:07:17 -0800106 break;
107 case KeyLocator_Name:
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800108 total_len += m_name.wireEncode(block);
Alexander Afanasyeve9a66e52014-01-17 16:07:17 -0800109 break;
110 default:
111 throw Error("Unsupported KeyLocator type");
112 }
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800113
114 total_len += block.prependVarNumber (total_len);
115 total_len += block.prependVarNumber (Tlv::KeyLocator);
116 return total_len;
117}
118
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700119inline const Block&
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800120KeyLocator::wireEncode() const
121{
122 if (m_wire.hasWire ())
123 return m_wire;
124
125 EncodingEstimator estimator;
126 size_t estimatedSize = wireEncode(estimator);
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700127
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800128 EncodingBuffer buffer(estimatedSize, 0);
129 wireEncode(buffer);
130
131 m_wire = buffer.block();
132 return m_wire;
Jeff Thompson5cae5e52013-07-10 19:41:20 -0700133}
134
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700135inline void
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800136KeyLocator::wireDecode(const Block &value)
137{
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800138 if (value.type() != Tlv::KeyLocator)
139 throw Error("Unexpected TLV type during KeyLocator decoding");
140
141 m_wire = value;
142 m_wire.parse();
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700143
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800144 if (!m_wire.elements().empty() && m_wire.elements_begin()->type() == Tlv::Name)
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800145 {
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800146 m_type = KeyLocator_Name;
147 m_name.wireDecode(*m_wire.elements_begin());
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800148 }
149 else
150 {
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800151 m_type = KeyLocator_Unknown;
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800152 }
153}
154
155inline const Name&
156KeyLocator::getName() const
157{
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800158 if (m_type != KeyLocator_Name)
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800159 throw Error("Requested Name, but KeyLocator is not of the Name type");
160
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800161 return m_name;
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800162}
163
164inline void
165KeyLocator::setName(const Name &name)
166{
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800167 m_type = KeyLocator_Name;
168 m_name = name;
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800169}
170
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700171inline bool
172KeyLocator::operator==(const KeyLocator& other) const
173{
174 if (this->getType() != other.getType()) {
175 return false;
176 }
177
178 switch (this->getType()) {
179 case KeyLocator_Name:
180 if (this->getName() != other.getName()) {
181 return false;
182 }
183 break;
184 }
185
186 return true;
187}
188
189inline bool
190KeyLocator::operator!=(const KeyLocator& other) const
191{
192 return !this->operator==(other);
193}
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800194
195} // namespace ndn
196
Jeff Thompson5cae5e52013-07-10 19:41:20 -0700197#endif