1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
|
#include "string.ih"
namespace
{
char const escapeChars[] = "abfnrtv";
char const escapeValue[] = {'\a', '\b', '\f', '\n', '\r', '\t', '\v'};
size_t handleOctal(string *dest, string const &src, size_t pos)
{
size_t pos2 = min(src.length(),
src.find_first_not_of("01234567", pos));
if (pos2 == pos + 1 && src[pos] == '0') // saw \0
{
*dest += static_cast<char>(0);
return pos2;
}
size_t const nOct = 3; // need exactly 3 octals
pos2 = min(pos + nOct, pos2);
if (pos2 != pos + nOct) // need exactly nOct octals
{
*dest += src[pos]; // add next char if not so
return pos + 1; // next to handle
}
A2x a2x(src.substr(pos, nOct));
size_t ch;
a2x >> oct >> ch; // convert substr. to octal
*dest += static_cast<char>(ch); // append the octal value
return pos2; // pos. of next to handle
}
size_t handleHex(string *dest, string const &src, size_t pos)
{
size_t const nHex = 2; // need exactly 2 hex digits
++pos; // skip the 'x'
size_t pos2 = min(pos + nHex,
src.find_first_not_of(
"0123456789abcdefABCDEF", pos));
if (pos2 != pos + nHex) // found a hex character?
{
*dest += src[pos - 1]; // add next char if so
return pos; // next char to handle
}
A2x a2x(src.substr(pos, nHex));
size_t ch;
a2x >> hex >> ch; // convert substr. to hex
*dest += static_cast<char>(ch); // append the hex value
return pos2; // pos. of next to handle
}
}
string String::unescape(string const &str)
{
string ret;
size_t prefix = 0; // prefix text before \-char
size_t pos = 0;
while (true)
{
pos = str.find('\\', pos);
ret += str.substr(prefix, pos - prefix);// append prefix
if (pos == string::npos) // done if no more \-chars
return ret;
++pos; // skip \-char
if (pos == str.length()) // \-char terminates: remove it
return ret; // since we're removing \-chars
int next = str[pos]; // determine next char
if (char const *cp = strchr(escapeChars, next))// escape sequence ?
{
ret += escapeValue[cp - escapeChars];// then assign escape char
++pos; // next character to handle
}
else if (strchr("01234567", next)) // handle octal values
pos = handleOctal(&ret, str, pos);
else if (next == 'x') // handle hex values
pos = handleHex(&ret, str, pos);
else // handle lone characters
ret += str[pos++];
prefix = pos;
}
}
//#include <string>
//#include <iostream>
//using namespace std;
//using namespace FBB;
//
//void out(char ch)
//{
// cout << static_cast<size_t>(static_cast<unsigned char>(ch)) << ", ";
//}
//
//int main()
//{
// while (true)
// {
// cout << "? ";
// string str;
//
// if (!getline(cin, str))
// return(0);
//
// cout << str << " -> ";
// str = String::unescape(str);
// cout << str << '\n';
//
// for_each(str.begin(), str.end(), out);
// cout << '\n';
// }
//}
|