blob: 78f32c90504ab3a7323dc3af277831c3b5ba1e18 [file] [log] [blame]
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2/**
3 * Copyright (C) 2013 Regents of the University of California.
4 * @author: Jeff Thompson <jefft0@remap.ucla.edu>
5 * @author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
6 * @author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
7 * See COPYING for copyright and distribution information.
8 */
9
Alexander Afanasyeve2dcdfd2014-02-07 15:53:28 -080010#include "common.hpp"
11
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -080012#include "name-component.hpp"
13
14#include "util/time.hpp"
15#include "util/string-helper.hpp"
16
17namespace ndn {
18namespace name {
19
20Component
21Component::fromEscapedString(const char *escapedString, size_t beginOffset, size_t endOffset)
22{
23 std::string trimmedString(escapedString + beginOffset, escapedString + endOffset);
24 trim(trimmedString);
25 std::string value = unescape(trimmedString);
26
27 if (value.find_first_not_of(".") == std::string::npos) {
28 // Special case for component of only periods.
29 if (value.size() <= 2)
30 // Zero, one or two periods is illegal. Ignore this component.
31 return Component();
32 else
33 // Remove 3 periods.
34 return Component((const uint8_t *)&value[3], value.size() - 3);
35 }
36 else
37 return Component((const uint8_t *)&value[0], value.size());
38}
39
40void
41Component::toEscapedString(std::ostream& result) const
42{
43 const uint8_t *valuePtr = value();
44 size_t valueSize = value_size();
45
46 bool gotNonDot = false;
47 for (unsigned i = 0; i < valueSize; ++i) {
48 if (valuePtr[i] != 0x2e) {
49 gotNonDot = true;
50 break;
51 }
52 }
53 if (!gotNonDot) {
54 // Special case for component of zero or more periods. Add 3 periods.
55 result << "...";
56 for (size_t i = 0; i < valueSize; ++i)
57 result << '.';
58 }
59 else {
60 // In case we need to escape, set to upper case hex and save the previous flags.
61 std::ios::fmtflags saveFlags = result.flags(std::ios::hex | std::ios::uppercase);
62
63 for (size_t i = 0; i < valueSize; ++i) {
64 uint8_t x = valuePtr[i];
65 // Check for 0-9, A-Z, a-z, (+), (-), (.), (_)
66 if ((x >= 0x30 && x <= 0x39) || (x >= 0x41 && x <= 0x5a) ||
67 (x >= 0x61 && x <= 0x7a) || x == 0x2b || x == 0x2d ||
68 x == 0x2e || x == 0x5f)
69 result << x;
70 else {
71 result << '%';
72 if (x < 16)
73 result << '0';
74 result << (unsigned int)x;
75 }
76 }
77
78 // Restore.
79 result.flags(saveFlags);
80 }
81}
82
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -080083int
84Component::compare(const Component& other) const
85{
86 // Imitate ndn_Exclude_compareComponents.
87 if (value_size() < other.value_size())
88 return -1;
89 if (value_size() > other.value_size())
90 return 1;
91
92 if (value_size() == 0)
93 return 0;
94
95 // The components are equal length. Just do a byte compare.
96 return std::memcmp(value(), other.value(), value_size());
97}
98
99// const Block &
100// wireEncode() const
101// {
102
103// }
104
105} // namespace name
106} // namespace ndn