blob: a6e4ea857f26a72778ab76115042f0912e757bd4 [file] [log] [blame]
Jeff Thompson47eecfc2013-07-07 22:56:46 -07001/**
2 * @author: Jeff Thompson
Jeff Thompson06f824a2013-07-08 17:14:30 -07003 * Derived from Interest.js by Meki Cheraoui.
Jeff Thompson47eecfc2013-07-07 22:56:46 -07004 * See COPYING for copyright and distribution information.
Jeff Thompsonb7f95562013-07-03 18:36:42 -07005 */
6
7#include "BinaryXMLEncoder.h"
8#include "BinaryXMLDecoder.h"
Jeff Thompson22552902013-07-07 21:26:20 -07009#include "BinaryXMLName.h"
Jeff Thompson8238d002013-07-10 11:56:49 -070010#include "BinaryXMLPublisherPublicKeyDigest.h"
Jeff Thompsonb7f95562013-07-03 18:36:42 -070011#include "BinaryXMLInterest.h"
12
Jeff Thompsonf084ec62013-07-09 12:32:52 -070013static ndn_Error encodeExclude(struct ndn_Exclude *exclude, struct ndn_BinaryXMLEncoder *encoder)
14{
15 if (exclude->nEntries == 0)
Jeff Thompson5e4a41e2013-07-09 13:52:09 -070016 return 0;
Jeff Thompsonf084ec62013-07-09 12:32:52 -070017
18 ndn_Error error;
19 if (error = ndn_BinaryXMLEncoder_writeElementStartDTag(encoder, ndn_BinaryXML_DTag_Exclude))
20 return error;
21
22 // TODO: Do we want to order the components (except for ANY)?
23 unsigned int i;
24 for (i = 0; i < exclude->nEntries; ++i) {
25 struct ndn_ExcludeEntry *entry = &exclude->entries[i];
26
27 if (entry->type == ndn_Exclude_COMPONENT) {
28 if (error = ndn_BinaryXMLEncoder_writeBlobDTagElement
29 (encoder, ndn_BinaryXML_DTag_Component, entry->component, entry->componentLength))
30 return error;
31 }
32 else if (entry->type == ndn_Exclude_ANY) {
33 if (error = ndn_BinaryXMLEncoder_writeElementStartDTag(encoder, ndn_BinaryXML_DTag_Any))
34 return error;
35 if (error = ndn_BinaryXMLEncoder_writeElementClose(encoder))
36 return error;
37 }
38 else
39 return NDN_ERROR_unrecognized_ndn_ExcludeType;
40 }
41
42 if (error = ndn_BinaryXMLEncoder_writeElementClose(encoder))
43 return error;
44
45 return 0;
46}
47
48static ndn_Error decodeExclude(struct ndn_Exclude *exclude, struct ndn_BinaryXMLDecoder *decoder)
49{
50 ndn_Error error;
51 if (error = ndn_BinaryXMLDecoder_readElementStartDTag(decoder, ndn_BinaryXML_DTag_Exclude))
52 return error;
53
54 exclude->nEntries = 0;
55 while (1) {
56 int gotExpectedTag;
57
58 if (error = ndn_BinaryXMLDecoder_peekDTag(decoder, ndn_BinaryXML_DTag_Component, &gotExpectedTag))
59 return error;
60 if (gotExpectedTag) {
61 // Component
62 unsigned char *component;
63 unsigned int componentLen;
64 if (error = ndn_BinaryXMLDecoder_readBinaryDTagElement(decoder, ndn_BinaryXML_DTag_Component, 0, &component, &componentLen))
65 return error;
66
67 // Add the component entry.
68 if (exclude->nEntries >= exclude->maxEntries)
69 return NDN_ERROR_read_an_entry_past_the_maximum_number_of_entries_allowed_in_the_exclude;
70 ndn_ExcludeEntry_init(exclude->entries + exclude->nEntries, ndn_Exclude_COMPONENT, component, componentLen);
71 ++exclude->nEntries;
72
73 continue;
74 }
75
76 if (error = ndn_BinaryXMLDecoder_peekDTag(decoder, ndn_BinaryXML_DTag_Any, &gotExpectedTag))
77 return error;
78 if (gotExpectedTag) {
79 // Any
80 if (error = ndn_BinaryXMLDecoder_readElementStartDTag(decoder, ndn_BinaryXML_DTag_Any))
81 return error;
82 if (error = ndn_BinaryXMLDecoder_readElementClose(decoder))
83 return error;
84
85 // Add the any entry.
86 if (exclude->nEntries >= exclude->maxEntries)
87 return NDN_ERROR_read_an_entry_past_the_maximum_number_of_entries_allowed_in_the_exclude;
88 ndn_ExcludeEntry_init(exclude->entries + exclude->nEntries, ndn_Exclude_ANY, 0, 0);
89 ++exclude->nEntries;
90
91 continue;
92 }
93
94 if (error = ndn_BinaryXMLDecoder_peekDTag(decoder, ndn_BinaryXML_DTag_Bloom, &gotExpectedTag))
95 return error;
96 if (gotExpectedTag) {
97 // Skip the Bloom and treat it as Any.
98 unsigned char *value;
99 unsigned int valueLen;
100 if (error = ndn_BinaryXMLDecoder_readBinaryDTagElement(decoder, ndn_BinaryXML_DTag_Bloom, 0, &value, &valueLen))
101 return error;
102
103 // Add the any entry.
104 if (exclude->nEntries >= exclude->maxEntries)
105 return NDN_ERROR_read_an_entry_past_the_maximum_number_of_entries_allowed_in_the_exclude;
106 ndn_ExcludeEntry_init(exclude->entries + exclude->nEntries, ndn_Exclude_ANY, 0, 0);
107 ++exclude->nEntries;
108
109 continue;
110 }
111
112 // Else no more entries.
113 break;
114 }
115
116 if (error = ndn_BinaryXMLDecoder_readElementClose(decoder))
117 return error;
118
119 return 0;
120}
121
Jeff Thompson06f824a2013-07-08 17:14:30 -0700122ndn_Error ndn_encodeBinaryXMLInterest(struct ndn_Interest *interest, struct ndn_BinaryXMLEncoder *encoder)
123{
124 ndn_Error error;
125 if (error = ndn_BinaryXMLEncoder_writeElementStartDTag(encoder, ndn_BinaryXML_DTag_Interest))
126 return error;
127
128 if (error = ndn_encodeBinaryXMLName(&interest->name, encoder))
129 return error;
130
131 if (interest->minSuffixComponents >= 0) {
132 if (error = ndn_BinaryXMLEncoder_writeUnsignedDecimalIntDTagElement
133 (encoder, ndn_BinaryXML_DTag_MinSuffixComponents, (unsigned int)interest->minSuffixComponents))
134 return error;
135 }
136 if (interest->maxSuffixComponents >= 0) {
137 if (error = ndn_BinaryXMLEncoder_writeUnsignedDecimalIntDTagElement
138 (encoder, ndn_BinaryXML_DTag_MaxSuffixComponents, (unsigned int)interest->maxSuffixComponents))
139 return error;
140 }
141
Jeff Thompson8238d002013-07-10 11:56:49 -0700142 // This will skip encoding if there is no publisherPublicKeyDigest.
143 if (error = ndn_encodeBinaryXMLPublisherPublicKeyDigest(&interest->publisherPublicKeyDigest, encoder))
144 return error;
Jeff Thompson06f824a2013-07-08 17:14:30 -0700145
Jeff Thompson8238d002013-07-10 11:56:49 -0700146 // This will skip encoding if there is no exclude.
Jeff Thompsonf084ec62013-07-09 12:32:52 -0700147 if (error = encodeExclude(&interest->exclude, encoder))
148 return error;
Jeff Thompson06f824a2013-07-08 17:14:30 -0700149
150 if (interest->childSelector >= 0) {
151 if (error = ndn_BinaryXMLEncoder_writeUnsignedDecimalIntDTagElement
152 (encoder, ndn_BinaryXML_DTag_ChildSelector, (unsigned int)interest->childSelector))
153 return error;
154 }
155 if (interest->answerOriginKind >= 0 && interest->answerOriginKind != ndn_Interest_DEFAULT_ANSWER_ORIGIN_KIND) {
156 if (error = ndn_BinaryXMLEncoder_writeUnsignedDecimalIntDTagElement
157 (encoder, ndn_BinaryXML_DTag_AnswerOriginKind, (unsigned int)interest->answerOriginKind))
158 return error;
159 }
160 if (interest->scope >= 0) {
161 if (error = ndn_BinaryXMLEncoder_writeUnsignedDecimalIntDTagElement
162 (encoder, ndn_BinaryXML_DTag_Scope, (unsigned int)interest->scope))
163 return error;
164 }
165
166 if (interest->interestLifetime >= 0) {
167 if (error = ndn_BinaryXMLEncoder_writeElementStartDTag(encoder, ndn_BinaryXML_DTag_InterestLifetime))
168 return error;
169
170 unsigned int ticks = (unsigned int)(((double)interest->interestLifetime / 1000.0) * 4096.0);
171 if (error = ndn_BinaryXMLEncoder_writeUnsignedIntBigEndianBlob(encoder, ticks))
172 return error;
173
174 if (error = ndn_BinaryXMLEncoder_writeElementClose(encoder))
175 return error;
176 }
177
178 if (interest->nonce && interest->nonceLength > 0) {
179 if (error = ndn_BinaryXMLEncoder_writeBlobDTagElement
180 (encoder, ndn_BinaryXML_DTag_Nonce, interest->nonce, interest->nonceLength))
181 return error;
182 }
183
184 if (error = ndn_BinaryXMLEncoder_writeElementClose(encoder))
185 return error;
186
187 return 0;
188}
189
Jeff Thompson8b666002013-07-08 01:16:26 -0700190ndn_Error ndn_decodeBinaryXMLInterest(struct ndn_Interest *interest, struct ndn_BinaryXMLDecoder *decoder)
Jeff Thompsonb7f95562013-07-03 18:36:42 -0700191{
Jeff Thompson8b666002013-07-08 01:16:26 -0700192 ndn_Error error;
Jeff Thompson22552902013-07-07 21:26:20 -0700193 if (error = ndn_BinaryXMLDecoder_readElementStartDTag(decoder, ndn_BinaryXML_DTag_Interest))
194 return error;
195
196 if (error = ndn_decodeBinaryXMLName(&interest->name, decoder))
197 return error;
198
199 if (error = ndn_BinaryXMLDecoder_readOptionalUnsignedIntegerDTagElement
200 (decoder, ndn_BinaryXML_DTag_MinSuffixComponents, &interest->minSuffixComponents))
201 return error;
202 if (error = ndn_BinaryXMLDecoder_readOptionalUnsignedIntegerDTagElement
203 (decoder, ndn_BinaryXML_DTag_MaxSuffixComponents, &interest->maxSuffixComponents))
204 return error;
Jeff Thompsonb7f95562013-07-03 18:36:42 -0700205
Jeff Thompson5633c302013-07-11 10:24:27 -0700206 if (error = ndn_decodeOptionalBinaryXMLPublisherPublicKeyDigest(&interest->publisherPublicKeyDigest, decoder))
Jeff Thompson22552902013-07-07 21:26:20 -0700207 return error;
Jeff Thompson22552902013-07-07 21:26:20 -0700208
Jeff Thompson5633c302013-07-11 10:24:27 -0700209 int gotExpectedTag;
Jeff Thompsonf084ec62013-07-09 12:32:52 -0700210 if (error = ndn_BinaryXMLDecoder_peekDTag(decoder, ndn_BinaryXML_DTag_Exclude, &gotExpectedTag))
211 return error;
212 if (gotExpectedTag) {
213 if (error = decodeExclude(&interest->exclude, decoder))
214 return error;
215 }
216 else
217 interest->exclude.nEntries = 0;
Jeff Thompson22552902013-07-07 21:26:20 -0700218
219 if (error = ndn_BinaryXMLDecoder_readOptionalUnsignedIntegerDTagElement
220 (decoder, ndn_BinaryXML_DTag_ChildSelector, &interest->childSelector))
221 return error;
222 if (error = ndn_BinaryXMLDecoder_readOptionalUnsignedIntegerDTagElement
223 (decoder, ndn_BinaryXML_DTag_AnswerOriginKind, &interest->answerOriginKind))
224 return error;
225 if (error = ndn_BinaryXMLDecoder_readOptionalUnsignedIntegerDTagElement
226 (decoder, ndn_BinaryXML_DTag_Scope, &interest->scope))
227 return error;
228
229 if (error = ndn_BinaryXMLDecoder_peekDTag(decoder, ndn_BinaryXML_DTag_InterestLifetime, &gotExpectedTag))
230 return error;
231 if (gotExpectedTag) {
232 unsigned char *interestLifetime;
233 unsigned int interestLifetimeLength;
234 if (error = ndn_BinaryXMLDecoder_readBinaryDTagElement
235 (decoder, ndn_BinaryXML_DTag_InterestLifetime, 0, &interestLifetime, &interestLifetimeLength))
236 return error;
237
Jeff Thompson06f824a2013-07-08 17:14:30 -0700238 interest->interestLifetime = (int)(1000.0 *
239 (double)ndn_BinaryXMLDecoder_bigEndianToUnsignedInt(interestLifetime, interestLifetimeLength) / 4096.0);
Jeff Thompson22552902013-07-07 21:26:20 -0700240 }
241 else
242 interest->interestLifetime = -1;
243
244 if (error = ndn_BinaryXMLDecoder_peekDTag(decoder, ndn_BinaryXML_DTag_Nonce, &gotExpectedTag))
245 return error;
246 if (gotExpectedTag) {
247 if (error = ndn_BinaryXMLDecoder_readBinaryDTagElement
248 (decoder, ndn_BinaryXML_DTag_Nonce, 0, &interest->nonce, &interest->nonceLength))
249 return error;
250 }
251 else {
252 interest->nonce = 0;
253 interest->nonceLength = 0;
254 }
255
256 if (error = ndn_BinaryXMLDecoder_readElementClose(decoder))
257 return error;
258
259 return 0;
Jeff Thompson06f824a2013-07-08 17:14:30 -0700260}