blob: 715cddbd0b05079380b9e224586ced40d0e38125 [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/**
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07003 * Copyright (c) 2013-2014, Regents of the University of California.
4 * All rights reserved.
5 *
6 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
7 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
8 *
9 * This file licensed under New BSD License. See COPYING for detailed information about
10 * ndn-cxx library copyright, permissions, and redistribution restrictions.
Jeff Thompson5cae5e52013-07-10 19:41:20 -070011 */
12
Jeff Thompson71b2f872013-12-17 12:03:17 -080013#ifndef NDN_KEY_LOCATOR_HPP
14#define NDN_KEY_LOCATOR_HPP
Jeff Thompson5cae5e52013-07-10 19:41:20 -070015
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080016#include "encoding/block.hpp"
Jeff Thompson2e6269c2013-08-22 10:36:00 -070017#include "name.hpp"
Jeff Thompson5cae5e52013-07-10 19:41:20 -070018
19namespace ndn {
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -080020
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -070021class KeyLocator
22{
Jeff Thompson5cae5e52013-07-10 19:41:20 -070023public:
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070024 class Error : public std::runtime_error
25 {
26 public:
27 explicit
28 Error(const std::string& what)
29 : std::runtime_error(what)
30 {
31 }
32 };
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070033
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -080034 enum {
Alexander Afanasyev9cae6682014-02-19 14:18:56 -080035 KeyLocator_None = 65535, // just an arbitrarily large number (used only internally)
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080036 KeyLocator_Name = 0,
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070037
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080038 KeyLocator_Unknown = 255
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -080039 };
Alexander Afanasyevfa13f8e2014-01-03 15:19:07 -080040
Jeff Thompson5cae5e52013-07-10 19:41:20 -070041 KeyLocator()
Alexander Afanasyev809805d2014-02-17 17:20:33 -080042 : m_type(KeyLocator_None)
Jeff Thompson5cae5e52013-07-10 19:41:20 -070043 {
Jeff Thompson5cae5e52013-07-10 19:41:20 -070044 }
Jeff Thompson5cae5e52013-07-10 19:41:20 -070045
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070046 KeyLocator(const Name& name)
47 {
48 setName(name);
49 }
50
51 /**
52 * @brief Create from wire encoding
53 */
54 explicit
55 KeyLocator(const Block& wire)
56 {
57 wireDecode(wire);
58 }
Alexander Afanasyevfa13f8e2014-01-03 15:19:07 -080059
Alexander Afanasyev809805d2014-02-17 17:20:33 -080060 ///////////////////////////////////////////////////////////////////////////////
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070061
Alexander Afanasyev809805d2014-02-17 17:20:33 -080062 template<bool T>
63 size_t
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070064 wireEncode(EncodingImpl<T>& block) const;
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080065
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070066 const Block&
Alexander Afanasyev809805d2014-02-17 17:20:33 -080067 wireEncode() const;
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070068
Alexander Afanasyev809805d2014-02-17 17:20:33 -080069 void
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070070 wireDecode(const Block& wire);
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070071
Alexander Afanasyev809805d2014-02-17 17:20:33 -080072 ///////////////////////////////////////////////////////////////////////////////
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070073
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070074 bool
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -080075 empty() const
76 {
Alexander Afanasyev809805d2014-02-17 17:20:33 -080077 return m_type == KeyLocator_None;
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -080078 }
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070079
80 uint32_t
Alexander Afanasyev809805d2014-02-17 17:20:33 -080081 getType() const { return m_type; }
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070082
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -080083 ////////////////////////////////////////////////////////
84 // Helper methods for different types of key locators
85 //
86 // For now only Name type is actually supported
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070087
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070088 const Name&
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080089 getName() const;
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -080090
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070091 void
92 setName(const Name& name);
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070093
94public: // EqualityComparable concept
95 bool
96 operator==(const KeyLocator& other) const;
97
98 bool
99 operator!=(const KeyLocator& other) const;
100
Jeff Thompson5cae5e52013-07-10 19:41:20 -0700101private:
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800102 uint32_t m_type;
103 Name m_name;
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700104
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800105 mutable Block m_wire;
Jeff Thompson5cae5e52013-07-10 19:41:20 -0700106};
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -0800107
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800108template<bool T>
109inline size_t
110KeyLocator::wireEncode(EncodingImpl<T>& block) const
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800111{
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800112 // KeyLocator ::= KEY-LOCATOR-TYPE TLV-LENGTH KeyLocatorValue
Alexander Afanasyeve9a66e52014-01-17 16:07:17 -0800113
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800114 // KeyLocatorValue ::= Name |
115 // KeyLocatorDigest | (not supported yet)
116 // ...
Alexander Afanasyeve9a66e52014-01-17 16:07:17 -0800117
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800118 // KeyLocatorDigest ::= KEY-LOCATOR-DIGEST-TYPE TLV-LENGTH BYTE+
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700119
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700120 size_t totalLength = 0;
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800121
122 switch (m_type) {
Alexander Afanasyeve9a66e52014-01-17 16:07:17 -0800123 case KeyLocator_None:
Alexander Afanasyeve9a66e52014-01-17 16:07:17 -0800124 break;
125 case KeyLocator_Name:
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700126 totalLength += m_name.wireEncode(block);
Alexander Afanasyeve9a66e52014-01-17 16:07:17 -0800127 break;
128 default:
129 throw Error("Unsupported KeyLocator type");
130 }
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800131
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700132 totalLength += block.prependVarNumber(totalLength);
133 totalLength += block.prependVarNumber(Tlv::KeyLocator);
134 return totalLength;
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800135}
136
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700137inline const Block&
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800138KeyLocator::wireEncode() const
139{
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700140 if (m_wire.hasWire())
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800141 return m_wire;
142
143 EncodingEstimator estimator;
144 size_t estimatedSize = wireEncode(estimator);
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700145
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800146 EncodingBuffer buffer(estimatedSize, 0);
147 wireEncode(buffer);
148
149 m_wire = buffer.block();
150 return m_wire;
Jeff Thompson5cae5e52013-07-10 19:41:20 -0700151}
152
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700153inline void
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700154KeyLocator::wireDecode(const Block& value)
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800155{
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800156 if (value.type() != Tlv::KeyLocator)
157 throw Error("Unexpected TLV type during KeyLocator decoding");
158
159 m_wire = value;
160 m_wire.parse();
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700161
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800162 if (!m_wire.elements().empty() && m_wire.elements_begin()->type() == Tlv::Name)
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800163 {
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800164 m_type = KeyLocator_Name;
165 m_name.wireDecode(*m_wire.elements_begin());
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800166 }
167 else
168 {
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800169 m_type = KeyLocator_Unknown;
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800170 }
171}
172
173inline const Name&
174KeyLocator::getName() const
175{
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800176 if (m_type != KeyLocator_Name)
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800177 throw Error("Requested Name, but KeyLocator is not of the Name type");
178
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800179 return m_name;
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800180}
181
182inline void
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700183KeyLocator::setName(const Name& name)
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800184{
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700185 m_wire.reset();
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800186 m_type = KeyLocator_Name;
187 m_name = name;
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800188}
189
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700190inline bool
191KeyLocator::operator==(const KeyLocator& other) const
192{
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700193 return wireEncode() == other.wireEncode();
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700194}
195
196inline bool
197KeyLocator::operator!=(const KeyLocator& other) const
198{
199 return !this->operator==(other);
200}
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800201
202} // namespace ndn
203
Jeff Thompson5cae5e52013-07-10 19:41:20 -0700204#endif