blob: d5d8e495ae857ea5fa346fcfb2ca443d4ca0a7ff [file] [log] [blame]
Jeff Thompson25b4e612013-10-10 16:03:24 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
Jeff Thompson47eecfc2013-07-07 22:56:46 -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 Thompson47eecfc2013-07-07 22:56:46 -07005 * See COPYING for copyright and distribution information.
Jeff Thompsonb7f95562013-07-03 18:36:42 -07006 */
7
8#ifndef NDN_INTEREST_HPP
Jeff Thompson2d27e2f2013-08-09 12:55:00 -07009#define NDN_INTEREST_HPP
Jeff Thompsonb7f95562013-07-03 18:36:42 -070010
Jeff Thompson53412192013-08-06 13:35:50 -070011#include "name.hpp"
12#include "publisher-public-key-digest.hpp"
Jeff Thompson25b4e612013-10-10 16:03:24 -070013#include "c/interest-types.h"
14#include "encoding/wire-format.hpp"
15
16struct ndn_ExcludeEntry;
17struct ndn_Exclude;
18struct ndn_Interest;
Jeff Thompsonb7f95562013-07-03 18:36:42 -070019
20namespace ndn {
Jeff Thompsonfe556862013-07-09 13:52:55 -070021
Jeff Thompson8238d002013-07-10 11:56:49 -070022/**
Jeff Thompson4dfca982013-12-03 11:53:26 -080023 * An Exclude holds a vector of Exclude::Entry.
Jeff Thompson8238d002013-07-10 11:56:49 -070024 */
Jeff Thompsonfe556862013-07-09 13:52:55 -070025class Exclude {
26public:
27 /**
28 * Create a new Exclude with no entries.
29 */
Jeff Thompson000a1e92013-12-03 12:10:27 -080030 Exclude()
31 {
Jeff Thompsonfe556862013-07-09 13:52:55 -070032 }
Jeff Thompsonf62f9f22013-11-26 17:22:54 -080033
34 /**
35 * An Exclude::Entry holds an ndn_ExcludeType, and if it is a COMPONENT, it holds the component value.
36 */
37 class Entry {
38 public:
39 /**
40 * Create an Exclude::Entry of type ndn_Exclude_ANY
41 */
42 Entry()
43 : type_(ndn_Exclude_ANY)
44 {
45 }
46
47 /**
48 * Create an Exclude::Entry of type ndn_Exclude_COMPONENT.
49 */
50 Entry(uint8_t *component, size_t componentLen)
51 : type_(ndn_Exclude_COMPONENT), component_(component, componentLen)
52 {
53 }
54
55 /**
56 * Create an Exclude::Entry of type ndn_Exclude_COMPONENT.
57 */
58 Entry(const Blob& component)
59 : type_(ndn_Exclude_COMPONENT), component_(component)
60 {
61 }
62
63 /**
64 * Set the type in the excludeEntryStruct and to point to this entry, without copying any memory.
65 * WARNING: The resulting pointer in excludeEntryStruct is invalid after a further use of this object which could reallocate memory.
66 * @param excludeEntryStruct the C ndn_ExcludeEntry struct to receive the pointer
67 */
68 void
69 get(struct ndn_ExcludeEntry& excludeEntryStruct) const;
70
Jeff Thompson000a1e92013-12-03 12:10:27 -080071 ndn_ExcludeType
72 getType() const { return type_; }
Jeff Thompsonf62f9f22013-11-26 17:22:54 -080073
Jeff Thompson000a1e92013-12-03 12:10:27 -080074 const Name::Component&
75 getComponent() const { return component_; }
Jeff Thompsonf62f9f22013-11-26 17:22:54 -080076
77 private:
78 ndn_ExcludeType type_;
79 Name::Component component_; /**< only used if type_ is ndn_Exclude_COMPONENT */
80 };
81
82 /**
83 * Get the number of entries.
84 * @return The number of entries.
85 */
Jeff Thompson97223af2013-09-24 17:01:27 -070086 size_t
Jeff Thompsonf62f9f22013-11-26 17:22:54 -080087 size() const { return entries_.size(); }
Jeff Thompsonfe556862013-07-09 13:52:55 -070088
Jeff Thompsonf62f9f22013-11-26 17:22:54 -080089 /**
90 * Get the entry at the given index.
91 * @param i The index of the entry, starting from 0.
92 * @return The entry at the index.
93 */
94 const Exclude::Entry&
95 get(size_t i) const { return entries_[i]; }
96
97 /**
98 * @deprecated Use size().
99 */
100 size_t
101 getEntryCount() const { return entries_.size(); }
102
103 /**
104 * @deprecated Use get(i).
105 */
106 const Exclude::Entry&
Jeff Thompson97223af2013-09-24 17:01:27 -0700107 getEntry(size_t i) const { return entries_[i]; }
Jeff Thompsonfe556862013-07-09 13:52:55 -0700108
109 /**
Jeff Thompson8238d002013-07-10 11:56:49 -0700110 * Set the excludeStruct to point to the entries in this Exclude, without copying any memory.
Jeff Thompsonfe556862013-07-09 13:52:55 -0700111 * WARNING: The resulting pointers in excludeStruct are invalid after a further use of this object which could reallocate memory.
Jeff Thompson8238d002013-07-10 11:56:49 -0700112 * @param excludeStruct a C ndn_Exclude struct where the entries array is already allocated
Jeff Thompsonfe556862013-07-09 13:52:55 -0700113 */
Jeff Thompson0050abe2013-09-17 12:50:25 -0700114 void
115 get(struct ndn_Exclude& excludeStruct) const;
Jeff Thompsonfe556862013-07-09 13:52:55 -0700116
117 /**
Jeff Thompson8238d002013-07-10 11:56:49 -0700118 * Clear this Exclude, and set the entries by copying from the ndn_Exclude struct.
Jeff Thompsonfe556862013-07-09 13:52:55 -0700119 * @param excludeStruct a C ndn_Exclude struct
120 */
Jeff Thompson0050abe2013-09-17 12:50:25 -0700121 void
122 set(const struct ndn_Exclude& excludeStruct);
Jeff Thompsonfe556862013-07-09 13:52:55 -0700123
124 /**
Jeff Thompson832d2972013-10-31 11:24:55 -0700125 * Append a new entry of type ndn_Exclude_ANY.
126 * @return This Exclude so that you can chain calls to append.
Jeff Thompsonfe556862013-07-09 13:52:55 -0700127 */
Jeff Thompson832d2972013-10-31 11:24:55 -0700128 Exclude&
129 appendAny()
Jeff Thompsonfe556862013-07-09 13:52:55 -0700130 {
Jeff Thompsonf62f9f22013-11-26 17:22:54 -0800131 entries_.push_back(Entry());
Jeff Thompson832d2972013-10-31 11:24:55 -0700132 return *this;
Jeff Thompsonfe556862013-07-09 13:52:55 -0700133 }
134
135 /**
Jeff Thompsonb096e492013-10-31 11:29:28 -0700136 * Append a new entry of type ndn_Exclude_COMPONENT, copying from component of length componentLength.
Jeff Thompson832d2972013-10-31 11:24:55 -0700137 * @param component A pointer to the component byte array.
138 * @param componentLength The length of component.
139 * @return This Exclude so that you can chain calls to append.
Jeff Thompsonfe556862013-07-09 13:52:55 -0700140 */
Jeff Thompson832d2972013-10-31 11:24:55 -0700141 Exclude&
142 appendComponent(uint8_t *component, size_t componentLength)
Jeff Thompsonfe556862013-07-09 13:52:55 -0700143 {
Jeff Thompsonf62f9f22013-11-26 17:22:54 -0800144 entries_.push_back(Entry(component, componentLength));
Jeff Thompson832d2972013-10-31 11:24:55 -0700145 return *this;
Jeff Thompsonfe556862013-07-09 13:52:55 -0700146 }
Jeff Thompson832d2972013-10-31 11:24:55 -0700147
148 /**
Jeff Thompsonb096e492013-10-31 11:29:28 -0700149 * Append a new entry of type ndn_Exclude_COMPONENT, taking another pointer to the Blob value.
Jeff Thompson832d2972013-10-31 11:24:55 -0700150 * @param component A blob with a pointer to an immutable array. The pointer is copied.
151 * @return This Exclude so that you can chain calls to append.
152 */
153 Exclude&
154 appendComponent(const Blob &component)
155 {
Jeff Thompsonf62f9f22013-11-26 17:22:54 -0800156 entries_.push_back(Entry(component));
Jeff Thompson832d2972013-10-31 11:24:55 -0700157 return *this;
158 }
159
160 /**
161 * @deprecated Use appendAny.
162 */
163 Exclude&
164 addAny() { return appendAny(); }
165
166 /**
167 * @deprecated Use appendComponent.
168 */
169 Exclude&
170 addComponent(uint8_t *component, size_t componentLength) { return appendComponent(component, componentLength); }
Jeff Thompsonfe556862013-07-09 13:52:55 -0700171
172 /**
173 * Clear all the entries.
174 */
Jeff Thompson0050abe2013-09-17 12:50:25 -0700175 void
Jeff Thompsonf62f9f22013-11-26 17:22:54 -0800176 clear()
177 {
Jeff Thompsonfe556862013-07-09 13:52:55 -0700178 entries_.clear();
179 }
180
Jeff Thompson37527d62013-08-21 11:15:54 -0700181 /**
182 * Encode this Exclude with elements separated by "," and ndn_Exclude_ANY shown as "*".
183 * @return the URI string
184 */
Jeff Thompson92342a92013-12-03 12:16:58 -0800185 std::string
186 toUri() const;
Jeff Thompson37527d62013-08-21 11:15:54 -0700187
Jeff Thompsonfe556862013-07-09 13:52:55 -0700188private:
Jeff Thompsonf62f9f22013-11-26 17:22:54 -0800189 std::vector<Entry> entries_;
Jeff Thompsonfe556862013-07-09 13:52:55 -0700190};
Jeff Thompsonb7f95562013-07-03 18:36:42 -0700191
Jeff Thompson8238d002013-07-10 11:56:49 -0700192/**
193 * An Interest holds a Name and other fields for an interest.
194 */
Jeff Thompsonb7f95562013-07-03 18:36:42 -0700195class Interest {
196public:
Jeff Thompson1b4a7b12013-11-15 12:00:02 -0800197 /**
198 * Create a new Interest for the given name and values.
199 * @param name
200 * @param minSuffixComponents
201 * @param maxSuffixComponents
202 * @param publisherPublicKeyDigest
203 * @param exclude
204 * @param childSelector
205 * @param answerOriginKind
206 * @param scope
207 * @param interestLifetimeMilliseconds
208 * @param nonce
209 */
Jeff Thompson1656e6a2013-08-29 18:01:48 -0700210 Interest(const Name& name, int minSuffixComponents, int maxSuffixComponents,
211 const PublisherPublicKeyDigest& publisherPublicKeyDigest, const Exclude& exclude, int childSelector, int answerOriginKind,
Jeff Thompson83bf07e2013-11-19 11:46:18 -0800212 int scope, Milliseconds interestLifetimeMilliseconds, const Blob& nonce)
Jeff Thompsonf59a87a2013-07-31 16:55:41 -0700213 : name_(name), minSuffixComponents_(minSuffixComponents), maxSuffixComponents_(maxSuffixComponents),
214 publisherPublicKeyDigest_(publisherPublicKeyDigest), exclude_(exclude), childSelector_(childSelector),
215 answerOriginKind_(answerOriginKind), scope_(scope), interestLifetimeMilliseconds_(interestLifetimeMilliseconds),
216 nonce_(nonce)
217 {
218 }
Jeff Thompson3f76e9e2013-08-21 13:14:58 -0700219
Jeff Thompson1b4a7b12013-11-15 12:00:02 -0800220 /**
221 * Create a new Interest with the given name and values, and "none" for the nonce.
222 * @param name
223 * @param minSuffixComponents
224 * @param maxSuffixComponents
225 * @param publisherPublicKeyDigest
226 * @param exclude
227 * @param childSelector
228 * @param answerOriginKind
229 * @param scope
230 * @param interestLifetimeMilliseconds
231 */
Jeff Thompson1656e6a2013-08-29 18:01:48 -0700232 Interest(const Name& name, int minSuffixComponents, int maxSuffixComponents,
233 const PublisherPublicKeyDigest& publisherPublicKeyDigest, const Exclude& exclude, int childSelector, int answerOriginKind,
Jeff Thompson9a8e82f2013-10-17 14:13:43 -0700234 int scope, Milliseconds interestLifetimeMilliseconds)
Jeff Thompson3f76e9e2013-08-21 13:14:58 -0700235 : name_(name), minSuffixComponents_(minSuffixComponents), maxSuffixComponents_(maxSuffixComponents),
236 publisherPublicKeyDigest_(publisherPublicKeyDigest), exclude_(exclude), childSelector_(childSelector),
237 answerOriginKind_(answerOriginKind), scope_(scope), interestLifetimeMilliseconds_(interestLifetimeMilliseconds)
238 {
239 }
240
Jeff Thompson1b4a7b12013-11-15 12:00:02 -0800241 /**
242 * Create a new Interest with the given name and interest lifetime and "none" for other values.
243 * @param name The name for the interest.
244 * @param interestLifetimeMilliseconds The interest lifetime in milliseconds, or -1 for none.
245 */
Jeff Thompson9a8e82f2013-10-17 14:13:43 -0700246 Interest(const Name& name, Milliseconds interestLifetimeMilliseconds)
Jeff Thompsonf62382a2013-08-21 16:33:39 -0700247 : name_(name)
248 {
249 construct();
250 interestLifetimeMilliseconds_ = interestLifetimeMilliseconds;
251 }
252
Jeff Thompson1b4a7b12013-11-15 12:00:02 -0800253 /**
254 * Create a new Interest with the given name and "none" for other values.
255 * @param name The name for the interest.
256 */
Jeff Thompson1656e6a2013-08-29 18:01:48 -0700257 Interest(const Name& name)
Jeff Thompson3f76e9e2013-08-21 13:14:58 -0700258 : name_(name)
259 {
Jeff Thompson3f76e9e2013-08-21 13:14:58 -0700260 construct();
261 }
262
Jeff Thompson1b4a7b12013-11-15 12:00:02 -0800263 /**
264 * Create a new Interest with an empty name and "none" for all values.
265 */
Jeff Thompson3f76e9e2013-08-21 13:14:58 -0700266 Interest()
267 {
268 construct();
269 }
Jeff Thompsonf59a87a2013-07-31 16:55:41 -0700270
Jeff Thompson1b4a7b12013-11-15 12:00:02 -0800271 /**
272 * Encode this Interest for a particular wire format.
273 * @param wireFormat A WireFormat object used to decode the input. If omitted, use WireFormat::getDefaultWireFormat().
274 * @return The encoded byte array.
275 */
Jeff Thompson0050abe2013-09-17 12:50:25 -0700276 Blob
277 wireEncode(WireFormat& wireFormat = *WireFormat::getDefaultWireFormat()) const
Jeff Thompsonb7f95562013-07-03 18:36:42 -0700278 {
Jeff Thompsonb0979fd2013-07-30 15:48:21 -0700279 return wireFormat.encodeInterest(*this);
Jeff Thompsonb7f95562013-07-03 18:36:42 -0700280 }
Jeff Thompson0050abe2013-09-17 12:50:25 -0700281
Jeff Thompson1b4a7b12013-11-15 12:00:02 -0800282 /**
283 * Decode the input using a particular wire format and update this Interest.
284 * @param input The input byte array to be decoded.
285 * @param inputLength The length of input.
286 * @param wireFormat A WireFormat object used to decode the input. If omitted, use WireFormat::getDefaultWireFormat().
287 */
Jeff Thompson0050abe2013-09-17 12:50:25 -0700288 void
Jeff Thompson97223af2013-09-24 17:01:27 -0700289 wireDecode(const uint8_t *input, size_t inputLength, WireFormat& wireFormat = *WireFormat::getDefaultWireFormat())
Jeff Thompsonb7f95562013-07-03 18:36:42 -0700290 {
291 wireFormat.decodeInterest(*this, input, inputLength);
292 }
Jeff Thompson0050abe2013-09-17 12:50:25 -0700293
Jeff Thompson1b4a7b12013-11-15 12:00:02 -0800294 /**
295 * Decode the input using a particular wire format and update this Interest.
296 * @param input The input byte array to be decoded.
297 * @param wireFormat A WireFormat object used to decode the input. If omitted, use WireFormat::getDefaultWireFormat().
298 */
Jeff Thompson0050abe2013-09-17 12:50:25 -0700299 void
Jeff Thompson10ad12a2013-09-24 16:19:11 -0700300 wireDecode(const std::vector<uint8_t>& input, WireFormat& wireFormat = *WireFormat::getDefaultWireFormat())
Jeff Thompsonb7f95562013-07-03 18:36:42 -0700301 {
Jeff Thompson67e9e0a2013-08-02 19:16:19 -0700302 wireDecode(&input[0], input.size(), wireFormat);
Jeff Thompsonb7f95562013-07-03 18:36:42 -0700303 }
Jeff Thompsond9e278c2013-07-08 15:20:13 -0700304
305 /**
Jeff Thompson13e280b2013-12-03 13:12:23 -0800306 * Encode the name according to the "NDN URI Scheme". If there are interest selectors, append "?" and
307 * added the selectors as a query string. For example "/test/name?ndn.ChildSelector=1".
308 * @return The URI string.
309 */
310 std::string
311 toUri() const;
312
313 /**
Jeff Thompsond9e278c2013-07-08 15:20:13 -0700314 * Set the interestStruct to point to the components in this interest, without copying any memory.
315 * WARNING: The resulting pointers in interestStruct are invalid after a further use of this object which could reallocate memory.
316 * @param interestStruct a C ndn_Interest struct where the name components array is already allocated.
317 */
Jeff Thompson0050abe2013-09-17 12:50:25 -0700318 void
319 get(struct ndn_Interest& interestStruct) const;
Jeff Thompsonb7f95562013-07-03 18:36:42 -0700320
Jeff Thompson0050abe2013-09-17 12:50:25 -0700321 Name&
322 getName() { return name_; }
Jeff Thompsonb7f95562013-07-03 18:36:42 -0700323
Jeff Thompson0050abe2013-09-17 12:50:25 -0700324 const Name&
325 getName() const { return name_; }
Jeff Thompsond345a5b2013-07-08 16:18:23 -0700326
Jeff Thompson0050abe2013-09-17 12:50:25 -0700327 int
328 getMinSuffixComponents() const { return minSuffixComponents_; }
Jeff Thompson0a681722013-07-08 16:21:54 -0700329
Jeff Thompson0050abe2013-09-17 12:50:25 -0700330 int
331 getMaxSuffixComponents() const { return maxSuffixComponents_; }
Jeff Thompson0a681722013-07-08 16:21:54 -0700332
Jeff Thompson0050abe2013-09-17 12:50:25 -0700333 PublisherPublicKeyDigest&
334 getPublisherPublicKeyDigest() { return publisherPublicKeyDigest_; }
335
336 const PublisherPublicKeyDigest&
337 getPublisherPublicKeyDigest() const { return publisherPublicKeyDigest_; }
Jeff Thompson0a681722013-07-08 16:21:54 -0700338
Jeff Thompson0050abe2013-09-17 12:50:25 -0700339 Exclude&
340 getExclude() { return exclude_; }
341
342 const Exclude&
343 getExclude() const { return exclude_; }
344
345 int
346 getChildSelector() const { return childSelector_; }
Jeff Thompson0a681722013-07-08 16:21:54 -0700347
Jeff Thompson0050abe2013-09-17 12:50:25 -0700348 int
349 getAnswerOriginKind() const { return answerOriginKind_; }
Jeff Thompsond345a5b2013-07-08 16:18:23 -0700350
Jeff Thompson0050abe2013-09-17 12:50:25 -0700351 int
352 getScope() const { return scope_; }
Jeff Thompson0a681722013-07-08 16:21:54 -0700353
Jeff Thompson9a8e82f2013-10-17 14:13:43 -0700354 Milliseconds
Jeff Thompson0050abe2013-09-17 12:50:25 -0700355 getInterestLifetimeMilliseconds() const { return interestLifetimeMilliseconds_; }
356
357 const Blob&
358 getNonce() const { return nonce_; }
Jeff Thompson22552902013-07-07 21:26:20 -0700359
Jeff Thompsonb7f95562013-07-03 18:36:42 -0700360 /**
361 * Clear this interest, and set the values by copying from the interest struct.
362 * @param interestStruct a C ndn_Interest struct
363 */
Jeff Thompson0050abe2013-09-17 12:50:25 -0700364 void
365 set(const struct ndn_Interest& interestStruct);
Jeff Thompsoneb316a82013-07-09 15:11:17 -0700366
Jeff Thompson4b70d3d2013-10-21 17:34:34 -0700367 void
368 setName(const Name& name) { name_ = name; }
369
Jeff Thompson0050abe2013-09-17 12:50:25 -0700370 void
Jeff Thompson83bf07e2013-11-19 11:46:18 -0800371 setMinSuffixComponents(int minSuffixComponents) { minSuffixComponents_ = minSuffixComponents; }
Jeff Thompsoneb316a82013-07-09 15:11:17 -0700372
Jeff Thompson0050abe2013-09-17 12:50:25 -0700373 void
Jeff Thompson83bf07e2013-11-19 11:46:18 -0800374 setMaxSuffixComponents(int maxSuffixComponents) { maxSuffixComponents_ = maxSuffixComponents; }
Jeff Thompsoneb316a82013-07-09 15:11:17 -0700375
Jeff Thompson0050abe2013-09-17 12:50:25 -0700376 void
Jeff Thompson83bf07e2013-11-19 11:46:18 -0800377 setChildSelector(int childSelector) { childSelector_ = childSelector; }
Jeff Thompsoneb316a82013-07-09 15:11:17 -0700378
Jeff Thompson0050abe2013-09-17 12:50:25 -0700379 void
Jeff Thompson83bf07e2013-11-19 11:46:18 -0800380 setAnswerOriginKind(int answerOriginKind) { answerOriginKind_ = answerOriginKind; }
Jeff Thompsoneb316a82013-07-09 15:11:17 -0700381
Jeff Thompson0050abe2013-09-17 12:50:25 -0700382 void
Jeff Thompson83bf07e2013-11-19 11:46:18 -0800383 setScope(int scope) { scope_ = scope; }
Jeff Thompsoneb316a82013-07-09 15:11:17 -0700384
Jeff Thompson0050abe2013-09-17 12:50:25 -0700385 void
Jeff Thompson83bf07e2013-11-19 11:46:18 -0800386 setInterestLifetimeMilliseconds(Milliseconds interestLifetimeMilliseconds) { interestLifetimeMilliseconds_ = interestLifetimeMilliseconds; }
Jeff Thompsoneb316a82013-07-09 15:11:17 -0700387
Jeff Thompson0050abe2013-09-17 12:50:25 -0700388 void
Jeff Thompson83bf07e2013-11-19 11:46:18 -0800389 setNonce(const Blob& nonce) { nonce_ = nonce; }
Jeff Thompsoneb316a82013-07-09 15:11:17 -0700390
Jeff Thompsonb7f95562013-07-03 18:36:42 -0700391private:
Jeff Thompson0050abe2013-09-17 12:50:25 -0700392 void
393 construct()
Jeff Thompsonc0486c12013-07-16 14:36:16 -0700394 {
Jeff Thompson2d27e2f2013-08-09 12:55:00 -0700395 minSuffixComponents_ = -1;
396 maxSuffixComponents_ = -1;
397 childSelector_ = -1;
398 answerOriginKind_ = -1;
399 scope_ = -1;
400 interestLifetimeMilliseconds_ = -1.0;
Jeff Thompsonc0486c12013-07-16 14:36:16 -0700401 }
Jeff Thompsonb7f95562013-07-03 18:36:42 -0700402
403 Name name_;
Jeff Thompson2d27e2f2013-08-09 12:55:00 -0700404 int minSuffixComponents_;
405 int maxSuffixComponents_;
406 PublisherPublicKeyDigest publisherPublicKeyDigest_;
Jeff Thompsonfe556862013-07-09 13:52:55 -0700407 Exclude exclude_;
Jeff Thompson2d27e2f2013-08-09 12:55:00 -0700408 int childSelector_;
409 int answerOriginKind_;
410 int scope_;
Jeff Thompson9a8e82f2013-10-17 14:13:43 -0700411 Milliseconds interestLifetimeMilliseconds_;
Jeff Thompson412226d2013-09-12 15:55:46 -0700412 Blob nonce_;
Jeff Thompsonb7f95562013-07-03 18:36:42 -0700413};
414
415}
416
417#endif