blob: f0700e2403c5e01bdff51ae5459e1957899cc1e7 [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
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -070016class KeyLocator
17{
Jeff Thompson5cae5e52013-07-10 19:41:20 -070018public:
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070019 class Error : public std::runtime_error
20 {
21 public:
22 explicit
23 Error(const std::string& what)
24 : std::runtime_error(what)
25 {
26 }
27 };
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070028
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -080029 enum {
Alexander Afanasyev9cae6682014-02-19 14:18:56 -080030 KeyLocator_None = 65535, // just an arbitrarily large number (used only internally)
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080031 KeyLocator_Name = 0,
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070032
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080033 KeyLocator_Unknown = 255
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -080034 };
Alexander Afanasyevfa13f8e2014-01-03 15:19:07 -080035
Jeff Thompson5cae5e52013-07-10 19:41:20 -070036 KeyLocator()
Alexander Afanasyev809805d2014-02-17 17:20:33 -080037 : m_type(KeyLocator_None)
Jeff Thompson5cae5e52013-07-10 19:41:20 -070038 {
Jeff Thompson5cae5e52013-07-10 19:41:20 -070039 }
Jeff Thompson5cae5e52013-07-10 19:41:20 -070040
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070041 KeyLocator(const Name& name)
42 {
43 setName(name);
44 }
45
46 /**
47 * @brief Create from wire encoding
48 */
49 explicit
50 KeyLocator(const Block& wire)
51 {
52 wireDecode(wire);
53 }
Alexander Afanasyevfa13f8e2014-01-03 15:19:07 -080054
Alexander Afanasyev809805d2014-02-17 17:20:33 -080055 ///////////////////////////////////////////////////////////////////////////////
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070056
Alexander Afanasyev809805d2014-02-17 17:20:33 -080057 template<bool T>
58 size_t
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070059 wireEncode(EncodingImpl<T>& block) const;
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080060
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070061 const Block&
Alexander Afanasyev809805d2014-02-17 17:20:33 -080062 wireEncode() const;
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070063
Alexander Afanasyev809805d2014-02-17 17:20:33 -080064 void
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070065 wireDecode(const Block& wire);
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070066
Alexander Afanasyev809805d2014-02-17 17:20:33 -080067 ///////////////////////////////////////////////////////////////////////////////
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070068
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070069 bool
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -080070 empty() const
71 {
Alexander Afanasyev809805d2014-02-17 17:20:33 -080072 return m_type == KeyLocator_None;
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -080073 }
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070074
75 uint32_t
Alexander Afanasyev809805d2014-02-17 17:20:33 -080076 getType() const { return m_type; }
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070077
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -080078 ////////////////////////////////////////////////////////
79 // Helper methods for different types of key locators
80 //
81 // For now only Name type is actually supported
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070082
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070083 const Name&
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080084 getName() const;
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -080085
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070086 void
87 setName(const Name& name);
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070088
89public: // EqualityComparable concept
90 bool
91 operator==(const KeyLocator& other) const;
92
93 bool
94 operator!=(const KeyLocator& other) const;
95
Jeff Thompson5cae5e52013-07-10 19:41:20 -070096private:
Alexander Afanasyev809805d2014-02-17 17:20:33 -080097 uint32_t m_type;
98 Name m_name;
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070099
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800100 mutable Block m_wire;
Jeff Thompson5cae5e52013-07-10 19:41:20 -0700101};
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -0800102
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800103template<bool T>
104inline size_t
105KeyLocator::wireEncode(EncodingImpl<T>& block) const
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800106{
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800107 // KeyLocator ::= KEY-LOCATOR-TYPE TLV-LENGTH KeyLocatorValue
Alexander Afanasyeve9a66e52014-01-17 16:07:17 -0800108
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800109 // KeyLocatorValue ::= Name |
110 // KeyLocatorDigest | (not supported yet)
111 // ...
Alexander Afanasyeve9a66e52014-01-17 16:07:17 -0800112
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800113 // KeyLocatorDigest ::= KEY-LOCATOR-DIGEST-TYPE TLV-LENGTH BYTE+
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700114
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700115 size_t totalLength = 0;
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800116
117 switch (m_type) {
Alexander Afanasyeve9a66e52014-01-17 16:07:17 -0800118 case KeyLocator_None:
Alexander Afanasyeve9a66e52014-01-17 16:07:17 -0800119 break;
120 case KeyLocator_Name:
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700121 totalLength += m_name.wireEncode(block);
Alexander Afanasyeve9a66e52014-01-17 16:07:17 -0800122 break;
123 default:
124 throw Error("Unsupported KeyLocator type");
125 }
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800126
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700127 totalLength += block.prependVarNumber(totalLength);
128 totalLength += block.prependVarNumber(Tlv::KeyLocator);
129 return totalLength;
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800130}
131
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700132inline const Block&
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800133KeyLocator::wireEncode() const
134{
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700135 if (m_wire.hasWire())
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800136 return m_wire;
137
138 EncodingEstimator estimator;
139 size_t estimatedSize = wireEncode(estimator);
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700140
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800141 EncodingBuffer buffer(estimatedSize, 0);
142 wireEncode(buffer);
143
144 m_wire = buffer.block();
145 return m_wire;
Jeff Thompson5cae5e52013-07-10 19:41:20 -0700146}
147
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700148inline void
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700149KeyLocator::wireDecode(const Block& value)
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800150{
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800151 if (value.type() != Tlv::KeyLocator)
152 throw Error("Unexpected TLV type during KeyLocator decoding");
153
154 m_wire = value;
155 m_wire.parse();
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700156
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800157 if (!m_wire.elements().empty() && m_wire.elements_begin()->type() == Tlv::Name)
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800158 {
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800159 m_type = KeyLocator_Name;
160 m_name.wireDecode(*m_wire.elements_begin());
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800161 }
162 else
163 {
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800164 m_type = KeyLocator_Unknown;
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800165 }
166}
167
168inline const Name&
169KeyLocator::getName() const
170{
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800171 if (m_type != KeyLocator_Name)
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800172 throw Error("Requested Name, but KeyLocator is not of the Name type");
173
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800174 return m_name;
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800175}
176
177inline void
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700178KeyLocator::setName(const Name& name)
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800179{
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700180 m_wire.reset();
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800181 m_type = KeyLocator_Name;
182 m_name = name;
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800183}
184
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700185inline bool
186KeyLocator::operator==(const KeyLocator& other) const
187{
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700188 return wireEncode() == other.wireEncode();
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700189}
190
191inline bool
192KeyLocator::operator!=(const KeyLocator& other) const
193{
194 return !this->operator==(other);
195}
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800196
197} // namespace ndn
198
Jeff Thompson5cae5e52013-07-10 19:41:20 -0700199#endif