blob: dcae6bf723817fa2b83d2319b851e7cc4de6a4c2 [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) {} };
19
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,
23
24 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 ///////////////////////////////////////////////////////////////////////////////
37
38 template<bool T>
39 size_t
40 wireEncode(EncodingImpl<T> &block) const;
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080041
Alexander Afanasyev809805d2014-02-17 17:20:33 -080042 const Block&
43 wireEncode() const;
44
45 void
46 wireDecode(const Block &wire);
47
48 ///////////////////////////////////////////////////////////////////////////////
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080049
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 }
55
56 uint32_t
Alexander Afanasyev809805d2014-02-17 17:20:33 -080057 getType() const { return m_type; }
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080058
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
63
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);
Jeff Thompson35a2bc12013-09-17 14:23:13 -070069
Jeff Thompson5cae5e52013-07-10 19:41:20 -070070private:
Alexander Afanasyev809805d2014-02-17 17:20:33 -080071 uint32_t m_type;
72 Name m_name;
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080073
Alexander Afanasyev809805d2014-02-17 17:20:33 -080074 mutable Block m_wire;
Jeff Thompson5cae5e52013-07-10 19:41:20 -070075};
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -080076
Alexander Afanasyevfa13f8e2014-01-03 15:19:07 -080077inline
78KeyLocator::KeyLocator(const Name &name)
79{
80 setName(name);
81}
82
Alexander Afanasyev809805d2014-02-17 17:20:33 -080083template<bool T>
84inline size_t
85KeyLocator::wireEncode(EncodingImpl<T>& block) const
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080086{
Alexander Afanasyev809805d2014-02-17 17:20:33 -080087 // KeyLocator ::= KEY-LOCATOR-TYPE TLV-LENGTH KeyLocatorValue
Alexander Afanasyeve9a66e52014-01-17 16:07:17 -080088
Alexander Afanasyev809805d2014-02-17 17:20:33 -080089 // KeyLocatorValue ::= Name |
90 // KeyLocatorDigest | (not supported yet)
91 // ...
Alexander Afanasyeve9a66e52014-01-17 16:07:17 -080092
Alexander Afanasyev809805d2014-02-17 17:20:33 -080093 // KeyLocatorDigest ::= KEY-LOCATOR-DIGEST-TYPE TLV-LENGTH BYTE+
94
95 size_t total_len = 0;
96
97 switch (m_type) {
Alexander Afanasyeve9a66e52014-01-17 16:07:17 -080098 case KeyLocator_None:
Alexander Afanasyeve9a66e52014-01-17 16:07:17 -080099 break;
100 case KeyLocator_Name:
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800101 total_len += m_name.wireEncode(block);
Alexander Afanasyeve9a66e52014-01-17 16:07:17 -0800102 break;
103 default:
104 throw Error("Unsupported KeyLocator type");
105 }
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800106
107 total_len += block.prependVarNumber (total_len);
108 total_len += block.prependVarNumber (Tlv::KeyLocator);
109 return total_len;
110}
111
112inline const Block&
113KeyLocator::wireEncode() const
114{
115 if (m_wire.hasWire ())
116 return m_wire;
117
118 EncodingEstimator estimator;
119 size_t estimatedSize = wireEncode(estimator);
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800120
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800121 EncodingBuffer buffer(estimatedSize, 0);
122 wireEncode(buffer);
123
124 m_wire = buffer.block();
125 return m_wire;
Jeff Thompson5cae5e52013-07-10 19:41:20 -0700126}
127
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800128inline void
129KeyLocator::wireDecode(const Block &value)
130{
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800131 if (value.type() != Tlv::KeyLocator)
132 throw Error("Unexpected TLV type during KeyLocator decoding");
133
134 m_wire = value;
135 m_wire.parse();
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800136
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800137 if (!m_wire.elements().empty() && m_wire.elements_begin()->type() == Tlv::Name)
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800138 {
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800139 m_type = KeyLocator_Name;
140 m_name.wireDecode(*m_wire.elements_begin());
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800141 }
142 else
143 {
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800144 m_type = KeyLocator_Unknown;
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800145 }
146}
147
148inline const Name&
149KeyLocator::getName() const
150{
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800151 if (m_type != KeyLocator_Name)
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800152 throw Error("Requested Name, but KeyLocator is not of the Name type");
153
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800154 return m_name;
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800155}
156
157inline void
158KeyLocator::setName(const Name &name)
159{
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800160 m_type = KeyLocator_Name;
161 m_name = name;
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800162}
163
164
165} // namespace ndn
166
Jeff Thompson5cae5e52013-07-10 19:41:20 -0700167#endif