blob: 3d05730eca3d364e9b16a6907804e6a432b68ab1 [file] [log] [blame]
Jeff Thompson9c41dfe2013-06-27 12:10:25 -07001/*
2 * Author: Jeff Thompson
3 *
4 * BSD license, See the LICENSE file for more information.
5 */
6
Jeff Thompsone6063512013-07-01 15:11:28 -07007#include <sstream>
Jeff Thompson9c41dfe2013-06-27 12:10:25 -07008#include "Name.hpp"
9
10using namespace std;
11
12namespace ndn {
13
Jeff Thompson4b2479a2013-07-02 15:37:39 -070014/**
15 * Write the value to result, escaping characters according to the NDN URI Scheme.
16 * This also adds "..." to a value with zero or more ".".
17 * @param value the buffer with the value to escape
18 * @param result the string stream to write to.
19 */
20static void toEscapedString(const vector<unsigned char> &value, ostringstream &result)
21{
22 bool gotNonDot = false;
23 for (unsigned i = 0; i < value.size(); ++i) {
24 if (value[i] != 0x2e) {
25 gotNonDot = true;
26 break;
27 }
28 }
29 if (!gotNonDot) {
30 // Special case for component of zero or more periods. Add 3 periods.
31 result << "...";
32 for (unsigned int i = 0; i < value.size(); ++i)
33 result << ".";
34 }
35 else {
36 // In case we need to escape, set to upper case hex and save the previous flags.
37 ios::fmtflags saveFlags = result.flags(ios::hex | ios::uppercase);
38
39 for (unsigned int i = 0; i < value.size(); ++i) {
40 unsigned char x = value[i];
41 // Check for 0-9, A-Z, a-z, (+), (-), (.), (_)
42 if (x >= 0x30 && x <= 0x39 || x >= 0x41 && x <= 0x5a ||
43 x >= 0x61 && x <= 0x7a || x == 0x2b || x == 0x2d ||
44 x == 0x2e || x == 0x5f)
45 result << x;
46 else {
47 result << "%";
48 if (x < 16)
49 result << "0";
50 result << (unsigned int)x;
51 }
52 }
53
54 // Restore.
55 result.flags(saveFlags);
56 }
57}
58
Jeff Thompson016ed642013-07-02 14:39:06 -070059void Name::get(struct ndn_Name &nameStruct)
Jeff Thompson48815112013-06-28 18:22:48 -070060{
Jeff Thompson016ed642013-07-02 14:39:06 -070061 if (nameStruct.maxComponents < components_.size())
62 throw runtime_error("nameStruct.maxComponents must be >= this name getNComponents()");
63
64 nameStruct.nComponents = components_.size();
65 for (unsigned int i = 0; i < nameStruct.nComponents; ++i)
66 components_[i].get(nameStruct.components[i]);
Jeff Thompson48815112013-06-28 18:22:48 -070067}
68
Jeff Thompsonb468c312013-07-01 17:50:14 -070069void Name::set(struct ndn_Name &nameStruct)
70{
71 clear();
Jeff Thompsonccb13c12013-07-01 18:16:00 -070072 for (unsigned int i = 0; i < nameStruct.nComponents; ++i)
Jeff Thompsonb468c312013-07-01 17:50:14 -070073 addComponent(nameStruct.components[i].value, nameStruct.components[i].valueLength);
74}
75
Jeff Thompsone6063512013-07-01 15:11:28 -070076std::string Name::to_uri()
77{
Jeff Thompson4b2479a2013-07-02 15:37:39 -070078 if (components_.size() == 0)
79 return "/";
80
81 ostringstream result;
Jeff Thompsonccb13c12013-07-01 18:16:00 -070082 for (unsigned int i = 0; i < components_.size(); ++i) {
Jeff Thompson4b2479a2013-07-02 15:37:39 -070083 result << "/";
84 toEscapedString(components_[i].getValue(), result);
Jeff Thompsone6063512013-07-01 15:11:28 -070085 }
86
Jeff Thompson4b2479a2013-07-02 15:37:39 -070087 return result.str();
Jeff Thompsone6063512013-07-01 15:11:28 -070088}
89
Jeff Thompson9c41dfe2013-06-27 12:10:25 -070090}