1 /*
2 * Copyright (C) 2007-2010 Anders Gavare. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * 3. The name of the author may not be used to endorse or promote products
13 * derived from this software without specific prior written permission.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28 #include "EscapedString.h"
29
30
EscapedString(const string & str)31 EscapedString::EscapedString(const string& str)
32 : m_str(str)
33 {
34 }
35
36
Generate() const37 string EscapedString::Generate() const
38 {
39 string result = "\"";
40
41 for (size_t i=0; i<m_str.length(); i++) {
42 char ch = m_str[i];
43
44 switch (ch) {
45 case '\n':
46 result += "\\n";
47 break;
48 case '\r':
49 result += "\\r";
50 break;
51 case '\t':
52 result += "\\t";
53 break;
54 case '"':
55 result += "\\\"";
56 break;
57 case '\\':
58 result += "\\\\";
59 break;
60 default:
61 result += ch;
62 }
63 }
64
65 result += "\"";
66
67 return result;
68 }
69
70
Decode(bool & success) const71 string EscapedString::Decode(bool& success) const
72 {
73 success = false;
74
75 // Not an escaped string? Then return failure.
76 if (m_str.size() < 2 || m_str[0] != '"'
77 || m_str[m_str.size() - 1] != '"')
78 return "";
79
80 string result = "";
81 size_t i;
82
83 for (i = 1; i < m_str.length() - 1; i++) {
84 char ch = m_str[i];
85
86 switch (ch) {
87 case '\\':
88 {
89 char ch2 = m_str[++i];
90 switch (ch2) {
91 case 'n':
92 result += '\n';
93 break;
94 case 'r':
95 result += '\r';
96 break;
97 case 't':
98 result += '\t';
99 break;
100 default:
101 result += ch2;
102 }
103 break;
104 }
105 default:
106 result += ch;
107 }
108 }
109
110 if (i == m_str.length() - 1)
111 success = true;
112
113 return result;
114 }
115
116
117 /*****************************************************************************/
118
119
120 #ifdef WITHUNITTESTS
121
Test_EscapedString_Generate()122 static void Test_EscapedString_Generate()
123 {
124 UnitTest::Assert("trivial escape: normal text",
125 EscapedString("hello world 123").Generate() ==
126 "\"hello world 123\"");
127
128 UnitTest::Assert("escape tab",
129 EscapedString("hi\tworld").Generate() ==
130 "\"hi\\tworld\"");
131
132 UnitTest::Assert("escape newline and carriage return",
133 EscapedString("hi\nworld\ragain").Generate() ==
134 "\"hi\\nworld\\ragain\"");
135
136 UnitTest::Assert("escape quotes",
137 EscapedString("hi'123\"456\"789").Generate() ==
138 "\"hi'123\\\"456\\\"789\"");
139
140 UnitTest::Assert("escaped escape char",
141 EscapedString("Hello\\world").Generate() ==
142 "\"Hello\\\\world\"");
143 }
144
Test_EscapedString_Decode()145 static void Test_EscapedString_Decode()
146 {
147 bool success = false;
148
149 UnitTest::Assert("trivial escape: normal text",
150 EscapedString("\"hello world 123\"").Decode(success) ==
151 "hello world 123");
152 UnitTest::Assert("success failed? (1)", success == true);
153
154 success = false;
155 UnitTest::Assert("escape tab",
156 EscapedString("\"hi\\tworld\"").Decode(success) ==
157 "hi\tworld");
158 UnitTest::Assert("success failed? (2)", success == true);
159
160 success = false;
161 UnitTest::Assert("escape newline and carriage return",
162 EscapedString("\"hi\\nworld\\ragain\"").Decode(success) ==
163 "hi\nworld\ragain");
164 UnitTest::Assert("success failed? (3)", success == true);
165
166 success = false;
167 UnitTest::Assert("escape quotes",
168 EscapedString("\"hi'123\\\"456\\\"789\"").Decode(success) ==
169 "hi'123\"456\"789");
170 UnitTest::Assert("success failed? (4)", success == true);
171
172 success = false;
173 UnitTest::Assert("escaped escape char",
174 EscapedString("\"Hello\\\\world\"").Decode(success) ==
175 "Hello\\world");
176 UnitTest::Assert("success failed? (5)", success == true);
177 }
178
Test_EscapedString_Decode_WithoutQuotes()179 static void Test_EscapedString_Decode_WithoutQuotes()
180 {
181 bool success = true;
182
183 UnitTest::Assert("trivial escape: normal text",
184 EscapedString("hello world 123").Decode(success) ==
185 "");
186 UnitTest::Assert("success should have failed", success == false);
187 }
188
UNITTESTS(EscapedString)189 UNITTESTS(EscapedString)
190 {
191 UNITTEST(Test_EscapedString_Generate);
192 UNITTEST(Test_EscapedString_Decode);
193 UNITTEST(Test_EscapedString_Decode_WithoutQuotes);
194 }
195
196 #endif
197