blob: 14a1b5e6d6d9bd043e23d5a388fd568ef11402d2 [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 Afanasyevff2d08f2014-04-07 18:28:25 -070018 class Error : public std::runtime_error
19 {
20 public:
21 explicit
22 Error(const std::string& what)
23 : std::runtime_error(what)
24 {
25 }
26 };
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070027
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -080028 enum {
Alexander Afanasyev9cae6682014-02-19 14:18:56 -080029 KeyLocator_None = 65535, // just an arbitrarily large number (used only internally)
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080030 KeyLocator_Name = 0,
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070031
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080032 KeyLocator_Unknown = 255
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -080033 };
Alexander Afanasyevfa13f8e2014-01-03 15:19:07 -080034
Jeff Thompson5cae5e52013-07-10 19:41:20 -070035 KeyLocator()
Alexander Afanasyev809805d2014-02-17 17:20:33 -080036 : m_type(KeyLocator_None)
Jeff Thompson5cae5e52013-07-10 19:41:20 -070037 {
Jeff Thompson5cae5e52013-07-10 19:41:20 -070038 }
Jeff Thompson5cae5e52013-07-10 19:41:20 -070039
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070040 KeyLocator(const Name& name)
41 {
42 setName(name);
43 }
44
45 /**
46 * @brief Create from wire encoding
47 */
48 explicit
49 KeyLocator(const Block& wire)
50 {
51 wireDecode(wire);
52 }
Alexander Afanasyevfa13f8e2014-01-03 15:19:07 -080053
Alexander Afanasyev809805d2014-02-17 17:20:33 -080054 ///////////////////////////////////////////////////////////////////////////////
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070055
Alexander Afanasyev809805d2014-02-17 17:20:33 -080056 template<bool T>
57 size_t
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070058 wireEncode(EncodingImpl<T>& block) const;
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080059
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070060 const Block&
Alexander Afanasyev809805d2014-02-17 17:20:33 -080061 wireEncode() const;
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070062
Alexander Afanasyev809805d2014-02-17 17:20:33 -080063 void
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070064 wireDecode(const Block& wire);
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070065
Alexander Afanasyev809805d2014-02-17 17:20:33 -080066 ///////////////////////////////////////////////////////////////////////////////
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070067
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070068 bool
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -080069 empty() const
70 {
Alexander Afanasyev809805d2014-02-17 17:20:33 -080071 return m_type == KeyLocator_None;
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -080072 }
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070073
74 uint32_t
Alexander Afanasyev809805d2014-02-17 17:20:33 -080075 getType() const { return m_type; }
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070076
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -080077 ////////////////////////////////////////////////////////
78 // Helper methods for different types of key locators
79 //
80 // For now only Name type is actually supported
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070081
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070082 const Name&
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080083 getName() const;
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -080084
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070085 void
86 setName(const Name& name);
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070087
88public: // EqualityComparable concept
89 bool
90 operator==(const KeyLocator& other) const;
91
92 bool
93 operator!=(const KeyLocator& other) const;
94
Jeff Thompson5cae5e52013-07-10 19:41:20 -070095private:
Alexander Afanasyev809805d2014-02-17 17:20:33 -080096 uint32_t m_type;
97 Name m_name;
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070098
Alexander Afanasyev809805d2014-02-17 17:20:33 -080099 mutable Block m_wire;
Jeff Thompson5cae5e52013-07-10 19:41:20 -0700100};
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -0800101
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800102template<bool T>
103inline size_t
104KeyLocator::wireEncode(EncodingImpl<T>& block) const
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800105{
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800106 // KeyLocator ::= KEY-LOCATOR-TYPE TLV-LENGTH KeyLocatorValue
Alexander Afanasyeve9a66e52014-01-17 16:07:17 -0800107
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800108 // KeyLocatorValue ::= Name |
109 // KeyLocatorDigest | (not supported yet)
110 // ...
Alexander Afanasyeve9a66e52014-01-17 16:07:17 -0800111
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800112 // KeyLocatorDigest ::= KEY-LOCATOR-DIGEST-TYPE TLV-LENGTH BYTE+
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700113
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700114 size_t totalLength = 0;
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800115
116 switch (m_type) {
Alexander Afanasyeve9a66e52014-01-17 16:07:17 -0800117 case KeyLocator_None:
Alexander Afanasyeve9a66e52014-01-17 16:07:17 -0800118 break;
119 case KeyLocator_Name:
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700120 totalLength += m_name.wireEncode(block);
Alexander Afanasyeve9a66e52014-01-17 16:07:17 -0800121 break;
122 default:
123 throw Error("Unsupported KeyLocator type");
124 }
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800125
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700126 totalLength += block.prependVarNumber(totalLength);
127 totalLength += block.prependVarNumber(Tlv::KeyLocator);
128 return totalLength;
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800129}
130
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700131inline const Block&
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800132KeyLocator::wireEncode() const
133{
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700134 if (m_wire.hasWire())
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800135 return m_wire;
136
137 EncodingEstimator estimator;
138 size_t estimatedSize = wireEncode(estimator);
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700139
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800140 EncodingBuffer buffer(estimatedSize, 0);
141 wireEncode(buffer);
142
143 m_wire = buffer.block();
144 return m_wire;
Jeff Thompson5cae5e52013-07-10 19:41:20 -0700145}
146
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700147inline void
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700148KeyLocator::wireDecode(const Block& value)
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800149{
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800150 if (value.type() != Tlv::KeyLocator)
151 throw Error("Unexpected TLV type during KeyLocator decoding");
152
153 m_wire = value;
154 m_wire.parse();
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700155
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800156 if (!m_wire.elements().empty() && m_wire.elements_begin()->type() == Tlv::Name)
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800157 {
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800158 m_type = KeyLocator_Name;
159 m_name.wireDecode(*m_wire.elements_begin());
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800160 }
161 else
162 {
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800163 m_type = KeyLocator_Unknown;
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800164 }
165}
166
167inline const Name&
168KeyLocator::getName() const
169{
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800170 if (m_type != KeyLocator_Name)
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800171 throw Error("Requested Name, but KeyLocator is not of the Name type");
172
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800173 return m_name;
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800174}
175
176inline void
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700177KeyLocator::setName(const Name& name)
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800178{
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700179 m_wire.reset();
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800180 m_type = KeyLocator_Name;
181 m_name = name;
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800182}
183
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700184inline bool
185KeyLocator::operator==(const KeyLocator& other) const
186{
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700187 return wireEncode() == other.wireEncode();
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700188}
189
190inline bool
191KeyLocator::operator!=(const KeyLocator& other) const
192{
193 return !this->operator==(other);
194}
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800195
196} // namespace ndn
197
Jeff Thompson5cae5e52013-07-10 19:41:20 -0700198#endif