blob: a139bf7a4448097c57b7edad40936f193e80ff02 [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 Afanasyevff2d08f2014-04-07 18:28:25 -070040 KeyLocator(const Name& name);
Alexander Afanasyevfa13f8e2014-01-03 15:19:07 -080041
Alexander Afanasyev809805d2014-02-17 17:20:33 -080042 ///////////////////////////////////////////////////////////////////////////////
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070043
Alexander Afanasyev809805d2014-02-17 17:20:33 -080044 template<bool T>
45 size_t
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070046 wireEncode(EncodingImpl<T>& block) const;
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080047
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070048 const Block&
Alexander Afanasyev809805d2014-02-17 17:20:33 -080049 wireEncode() const;
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070050
Alexander Afanasyev809805d2014-02-17 17:20:33 -080051 void
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070052 wireDecode(const Block& wire);
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070053
Alexander Afanasyev809805d2014-02-17 17:20:33 -080054 ///////////////////////////////////////////////////////////////////////////////
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070055
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070056 bool
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -080057 empty() const
58 {
Alexander Afanasyev809805d2014-02-17 17:20:33 -080059 return m_type == KeyLocator_None;
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -080060 }
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070061
62 uint32_t
Alexander Afanasyev809805d2014-02-17 17:20:33 -080063 getType() const { return m_type; }
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070064
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -080065 ////////////////////////////////////////////////////////
66 // Helper methods for different types of key locators
67 //
68 // For now only Name type is actually supported
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070069
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070070 const Name&
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080071 getName() const;
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -080072
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070073 void
74 setName(const Name& name);
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070075
76public: // EqualityComparable concept
77 bool
78 operator==(const KeyLocator& other) const;
79
80 bool
81 operator!=(const KeyLocator& other) const;
82
Jeff Thompson5cae5e52013-07-10 19:41:20 -070083private:
Alexander Afanasyev809805d2014-02-17 17:20:33 -080084 uint32_t m_type;
85 Name m_name;
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070086
Alexander Afanasyev809805d2014-02-17 17:20:33 -080087 mutable Block m_wire;
Jeff Thompson5cae5e52013-07-10 19:41:20 -070088};
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -080089
Alexander Afanasyevfa13f8e2014-01-03 15:19:07 -080090inline
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070091KeyLocator::KeyLocator(const Name& name)
Alexander Afanasyevfa13f8e2014-01-03 15:19:07 -080092{
93 setName(name);
94}
95
Alexander Afanasyev809805d2014-02-17 17:20:33 -080096template<bool T>
97inline size_t
98KeyLocator::wireEncode(EncodingImpl<T>& block) const
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080099{
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800100 // KeyLocator ::= KEY-LOCATOR-TYPE TLV-LENGTH KeyLocatorValue
Alexander Afanasyeve9a66e52014-01-17 16:07:17 -0800101
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800102 // KeyLocatorValue ::= Name |
103 // KeyLocatorDigest | (not supported yet)
104 // ...
Alexander Afanasyeve9a66e52014-01-17 16:07:17 -0800105
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800106 // KeyLocatorDigest ::= KEY-LOCATOR-DIGEST-TYPE TLV-LENGTH BYTE+
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700107
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800108 size_t total_len = 0;
109
110 switch (m_type) {
Alexander Afanasyeve9a66e52014-01-17 16:07:17 -0800111 case KeyLocator_None:
Alexander Afanasyeve9a66e52014-01-17 16:07:17 -0800112 break;
113 case KeyLocator_Name:
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800114 total_len += m_name.wireEncode(block);
Alexander Afanasyeve9a66e52014-01-17 16:07:17 -0800115 break;
116 default:
117 throw Error("Unsupported KeyLocator type");
118 }
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800119
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700120 total_len += block.prependVarNumber(total_len);
121 total_len += block.prependVarNumber(Tlv::KeyLocator);
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800122 return total_len;
123}
124
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700125inline const Block&
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800126KeyLocator::wireEncode() const
127{
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700128 if (m_wire.hasWire())
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800129 return m_wire;
130
131 EncodingEstimator estimator;
132 size_t estimatedSize = wireEncode(estimator);
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700133
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800134 EncodingBuffer buffer(estimatedSize, 0);
135 wireEncode(buffer);
136
137 m_wire = buffer.block();
138 return m_wire;
Jeff Thompson5cae5e52013-07-10 19:41:20 -0700139}
140
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700141inline void
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700142KeyLocator::wireDecode(const Block& value)
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800143{
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800144 if (value.type() != Tlv::KeyLocator)
145 throw Error("Unexpected TLV type during KeyLocator decoding");
146
147 m_wire = value;
148 m_wire.parse();
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700149
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800150 if (!m_wire.elements().empty() && m_wire.elements_begin()->type() == Tlv::Name)
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800151 {
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800152 m_type = KeyLocator_Name;
153 m_name.wireDecode(*m_wire.elements_begin());
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800154 }
155 else
156 {
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800157 m_type = KeyLocator_Unknown;
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800158 }
159}
160
161inline const Name&
162KeyLocator::getName() const
163{
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800164 if (m_type != KeyLocator_Name)
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800165 throw Error("Requested Name, but KeyLocator is not of the Name type");
166
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800167 return m_name;
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800168}
169
170inline void
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700171KeyLocator::setName(const Name& name)
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800172{
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700173 m_wire.reset();
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800174 m_type = KeyLocator_Name;
175 m_name = name;
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800176}
177
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700178inline bool
179KeyLocator::operator==(const KeyLocator& other) const
180{
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700181 return wireEncode() == other.wireEncode();
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700182}
183
184inline bool
185KeyLocator::operator!=(const KeyLocator& other) const
186{
187 return !this->operator==(other);
188}
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800189
190} // namespace ndn
191
Jeff Thompson5cae5e52013-07-10 19:41:20 -0700192#endif