blob: 13b0b31e14a97bf1d967ffa3a4ba4068aedceae5 [file] [log] [blame]
Alexander Afanasyevaf283d82014-01-03 13:23:34 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2/**
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07003 * Copyright (c) 2013-2014, Regents of the University of California.
4 * All rights reserved.
5 *
6 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
7 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
8 *
9 * This file licensed under New BSD License. See COPYING for detailed information about
10 * ndn-cxx library copyright, permissions, and redistribution restrictions.
11 *
12 * @author Jeff Thompson <jefft0@remap.ucla.edu>
Alexander Afanasyevaf283d82014-01-03 13:23:34 -080013 */
14
15#ifndef NDN_STRING_HELPER_HPP
16#define NDN_STRING_HELPER_HPP
17
18#include <string>
19#include <sstream>
20
21namespace ndn {
22
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070023static const char* WHITESPACE_CHARS = " \n\r\t";
Alexander Afanasyevaf283d82014-01-03 13:23:34 -080024
25/**
Alexander Afanasyev770827c2014-05-13 17:42:55 -070026 * @brief Return the hex representation of the bytes in array
27 *
28 * @param array The array of bytes
29 * @param arraySize Size of the array
Alexander Afanasyev809805d2014-02-17 17:20:33 -080030 */
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070031inline std::string
Alexander Afanasyev809805d2014-02-17 17:20:33 -080032toHex(const uint8_t* array, size_t arraySize)
33{
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -070034 if (array == 0 || arraySize == 0)
Alexander Afanasyev809805d2014-02-17 17:20:33 -080035 return "";
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070036
Alexander Afanasyev809805d2014-02-17 17:20:33 -080037 std::ostringstream result;
38 result.flags(std::ios::hex | std::ios::uppercase);
39 for (size_t i = 0; i < arraySize; ++i) {
40 uint8_t x = array[i];
41 if (x < 16)
42 result << '0';
43 result << (unsigned int)x;
44 }
45
46 return result.str();
47}
48
49/**
Alexander Afanasyev770827c2014-05-13 17:42:55 -070050 * @brief Modify str in place to erase whitespace on the left
Alexander Afanasyevaf283d82014-01-03 13:23:34 -080051 */
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070052inline void
Alexander Afanasyevaf283d82014-01-03 13:23:34 -080053trimLeft(std::string& str)
54{
55 size_t found = str.find_first_not_of(WHITESPACE_CHARS);
56 if (found != std::string::npos) {
57 if (found > 0)
58 str.erase(0, found);
59 }
60 else
61 // All whitespace
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070062 str.clear();
Alexander Afanasyevaf283d82014-01-03 13:23:34 -080063}
64
65/**
Alexander Afanasyev770827c2014-05-13 17:42:55 -070066 * @brief Modify str in place to erase whitespace on the right
Alexander Afanasyevaf283d82014-01-03 13:23:34 -080067 */
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070068inline void
Alexander Afanasyevaf283d82014-01-03 13:23:34 -080069trimRight(std::string& str)
70{
71 size_t found = str.find_last_not_of(WHITESPACE_CHARS);
72 if (found != std::string::npos) {
73 if (found + 1 < str.size())
74 str.erase(found + 1);
75 }
76 else
77 // All whitespace
78 str.clear();
79}
80
81/**
Alexander Afanasyev770827c2014-05-13 17:42:55 -070082 * @brief Modify str in place to erase whitespace on the left and right
Alexander Afanasyevaf283d82014-01-03 13:23:34 -080083 */
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070084inline void
Alexander Afanasyevaf283d82014-01-03 13:23:34 -080085trim(std::string& str)
86{
87 trimLeft(str);
88 trimRight(str);
89}
90
91/**
Alexander Afanasyev770827c2014-05-13 17:42:55 -070092 * @brief Convert the hex character to an integer from 0 to 15, or -1 if not a hex character
Alexander Afanasyevaf283d82014-01-03 13:23:34 -080093 */
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070094inline int
Alexander Afanasyevaf283d82014-01-03 13:23:34 -080095fromHexChar(uint8_t c)
96{
97 if (c >= '0' && c <= '9')
98 return (int)c - (int)'0';
99 else if (c >= 'A' && c <= 'F')
100 return (int)c - (int)'A' + 10;
101 else if (c >= 'a' && c <= 'f')
102 return (int)c - (int)'a' + 10;
103 else
104 return -1;
105}
106
107/**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700108 * @brief Return a copy of str, converting each escaped "%XX" to the char value
Alexander Afanasyevaf283d82014-01-03 13:23:34 -0800109 */
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700110inline std::string
Alexander Afanasyevaf283d82014-01-03 13:23:34 -0800111unescape(const std::string& str)
112{
113 std::ostringstream result;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700114
Alexander Afanasyevaf283d82014-01-03 13:23:34 -0800115 for (size_t i = 0; i < str.size(); ++i) {
116 if (str[i] == '%' && i + 2 < str.size()) {
117 int hi = fromHexChar(str[i + 1]);
118 int lo = fromHexChar(str[i + 2]);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700119
Alexander Afanasyevaf283d82014-01-03 13:23:34 -0800120 if (hi < 0 || lo < 0)
121 // Invalid hex characters, so just keep the escaped string.
122 result << str[i] << str[i + 1] << str[i + 2];
123 else
124 result << (uint8_t)(16 * hi + lo);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700125
Alexander Afanasyevaf283d82014-01-03 13:23:34 -0800126 // Skip ahead past the escaped value.
127 i += 2;
128 }
129 else
130 // Just copy through.
131 result << str[i];
132 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700133
Alexander Afanasyevaf283d82014-01-03 13:23:34 -0800134 return result.str();
135}
136
137} // namespace ndn
138
139#endif // NDN_STRING_HELPER_HPP