Implment to_uri with toEscapedString,
diff --git a/ndn-cpp/Name.cpp b/ndn-cpp/Name.cpp
index 3b98fa7..3d05730 100644
--- a/ndn-cpp/Name.cpp
+++ b/ndn-cpp/Name.cpp
@@ -11,6 +11,51 @@
namespace ndn {
+/**
+ * Write the value to result, escaping characters according to the NDN URI Scheme.
+ * This also adds "..." to a value with zero or more ".".
+ * @param value the buffer with the value to escape
+ * @param result the string stream to write to.
+ */
+static void toEscapedString(const vector<unsigned char> &value, ostringstream &result)
+{
+ bool gotNonDot = false;
+ for (unsigned i = 0; i < value.size(); ++i) {
+ if (value[i] != 0x2e) {
+ gotNonDot = true;
+ break;
+ }
+ }
+ if (!gotNonDot) {
+ // Special case for component of zero or more periods. Add 3 periods.
+ result << "...";
+ for (unsigned int i = 0; i < value.size(); ++i)
+ result << ".";
+ }
+ else {
+ // In case we need to escape, set to upper case hex and save the previous flags.
+ ios::fmtflags saveFlags = result.flags(ios::hex | ios::uppercase);
+
+ for (unsigned int i = 0; i < value.size(); ++i) {
+ unsigned char x = value[i];
+ // Check for 0-9, A-Z, a-z, (+), (-), (.), (_)
+ if (x >= 0x30 && x <= 0x39 || x >= 0x41 && x <= 0x5a ||
+ x >= 0x61 && x <= 0x7a || x == 0x2b || x == 0x2d ||
+ x == 0x2e || x == 0x5f)
+ result << x;
+ else {
+ result << "%";
+ if (x < 16)
+ result << "0";
+ result << (unsigned int)x;
+ }
+ }
+
+ // Restore.
+ result.flags(saveFlags);
+ }
+}
+
void Name::get(struct ndn_Name &nameStruct)
{
if (nameStruct.maxComponents < components_.size())
@@ -30,15 +75,16 @@
std::string Name::to_uri()
{
- // TODO: implement fully.
- ostringstream output;
+ if (components_.size() == 0)
+ return "/";
+
+ ostringstream result;
for (unsigned int i = 0; i < components_.size(); ++i) {
- output << "/";
- for (unsigned int j = 0; j < components_[i].getValue().size(); ++j)
- output << components_[i].getValue()[j];
+ result << "/";
+ toEscapedString(components_[i].getValue(), result);
}
- return output.str();
+ return result.str();
}
}