summaryrefslogtreecommitdiff
path: root/cpp/src/Ice/StringUtil.cpp
diff options
context:
space:
mode:
authorMark Spruiell <mes@zeroc.com>2002-08-27 18:46:05 +0000
committerMark Spruiell <mes@zeroc.com>2002-08-27 18:46:05 +0000
commitfcd354c185711a2936a053fdd22bf7deb5691705 (patch)
tree8ee9c346cfc28f17fad8079f56d253f7ed96c5d9 /cpp/src/Ice/StringUtil.cpp
parentinitial check-in (diff)
downloadice-fcd354c185711a2936a053fdd22bf7deb5691705.tar.bz2
ice-fcd354c185711a2936a053fdd22bf7deb5691705.tar.xz
ice-fcd354c185711a2936a053fdd22bf7deb5691705.zip
adding escapes for references, identity
Diffstat (limited to 'cpp/src/Ice/StringUtil.cpp')
-rw-r--r--cpp/src/Ice/StringUtil.cpp273
1 files changed, 273 insertions, 0 deletions
diff --git a/cpp/src/Ice/StringUtil.cpp b/cpp/src/Ice/StringUtil.cpp
new file mode 100644
index 00000000000..2a2ebabcee2
--- /dev/null
+++ b/cpp/src/Ice/StringUtil.cpp
@@ -0,0 +1,273 @@
+// **********************************************************************
+//
+// Copyright (c) 2002
+// Mutable Realms, Inc.
+// Huntsville, AL, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#include <Ice/Config.h>
+#include <Ice/StringUtil.h>
+
+using namespace std;
+
+static string
+toOctalString(unsigned int n)
+{
+ string s;
+ s.resize(32);
+ string::size_type charPos = 32;
+ const int radix = 1 << 3;
+ int mask = radix - 1;
+ do
+ {
+ s[--charPos] = '0' + (n & mask);
+ n >>= 3;
+ }
+ while(n != 0);
+
+ return string(s, charPos, (32 - charPos));
+}
+
+static void
+encodeChar(string::value_type b, string& s, const string& special)
+{
+ switch(b)
+ {
+ case '\\':
+ {
+ s.append("\\\\");
+ break;
+ }
+ case '\'':
+ {
+ s.append("\\'");
+ break;
+ }
+ case '"':
+ {
+ s.append("\\\"");
+ break;
+ }
+ case '\b':
+ {
+ s.append("\\b");
+ break;
+ }
+ case '\f':
+ {
+ s.append("\\f");
+ break;
+ }
+ case '\n':
+ {
+ s.append("\\n");
+ break;
+ }
+ case '\r':
+ {
+ s.append("\\r");
+ break;
+ }
+ case '\t':
+ {
+ s.append("\\t");
+ break;
+ }
+ default:
+ {
+ if(((signed char)b) <= 31 || b == 127)
+ {
+ s.push_back('\\');
+ string octal = toOctalString(b);
+ //
+ // Add leading zeroes so that we avoid problems during
+ // decoding. For example, consider the encoded string
+ // \0013 (i.e., a character with value 1 followed by
+ // the character '3'). If the leading zeroes were omitted,
+ // the result would be incorrectly interpreted by the
+ // decoder as a single character with value 11.
+ //
+ for(string::size_type j = octal.size(); j < 3; j++)
+ {
+ s.push_back('0');
+ }
+ s.append(octal);
+ }
+ else if(special.find(b) != string::npos)
+ {
+ s.push_back('\\');
+ encodeChar(b, s, "");
+ }
+ else
+ {
+ s.push_back(b);
+ }
+ }
+ }
+}
+
+//
+// Encodes a string into UTF8, escaping all characters outside the range [32-126]
+// as well as any special characters determined by the caller.
+//
+string
+IceInternal::encodeString(const string& s, const string& special)
+{
+ string result;
+ result.reserve(s.size());
+
+ for(string::size_type i = 0; i < s.size(); i++)
+ {
+ encodeChar(s[i], result, special);
+ }
+
+ return result;
+}
+
+//
+// Decodes a UTF8 string. Decoding starts at the given start position
+// (inclusive) and stops at the given end position (exclusive). If the end
+// position is zero, then the remainder of the string is used. Upon success,
+// the result parameter holds the decoded string and true is returned.
+// A return value of false indicates an error was detected in the encoding.
+//
+bool
+IceInternal::decodeString(const string& s, string::size_type start, string::size_type end, string& result)
+{
+ const string::size_type len = s.size();
+ if(end == 0)
+ {
+ end = len;
+ }
+ assert(start >= 0);
+ assert(end <= len);
+ assert(start < end);
+
+ while(start < end)
+ {
+ string::size_type ch = s[start];
+ if(ch == '\\')
+ {
+ start++;
+ if(start == end)
+ {
+ return false; // Missing character
+ }
+ ch = s[start];
+ switch(ch)
+ {
+ case '\\':
+ {
+ result.push_back('\\');
+ break;
+ }
+ case '\'':
+ case '"':
+ {
+ result.push_back(ch);
+ break;
+ }
+ case 'b':
+ {
+ result.push_back('\b');
+ break;
+ }
+ case 'f':
+ {
+ result.push_back('\f');
+ break;
+ }
+ case 'n':
+ {
+ result.push_back('\n');
+ break;
+ }
+ case 'r':
+ {
+ result.push_back('\r');
+ break;
+ }
+ case 't':
+ {
+ result.push_back('\t');
+ break;
+ }
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ {
+ int count = 0;
+ int val = 0;
+ while(count < 3 && start < end && s[start] >= '0' && s[start] <= '9')
+ {
+ val <<= 3;
+ val |= s[start] - '0';
+ start++;
+ count++;
+ }
+ if(val > 255)
+ {
+ return false; // Octal value out of range
+ }
+ result.push_back((string::value_type)val);
+ continue; // don't increment start
+ }
+ default:
+ {
+ if(((signed char)ch) <= 31 || ch == 127)
+ {
+ return false; // Malformed encoding
+ }
+ else
+ {
+ result.push_back(ch);
+ }
+ }
+ }
+ }
+ else
+ {
+ result.push_back(ch);
+ }
+ start++;
+ }
+
+ return true;
+}
+
+//
+// If a single or double quotation mark is found at the start position,
+// then the position of the matching closing quote is returned. If no
+// quotation mark is found at the start position, then 0 is returned.
+// If no matching closing quote is found, then -1 is returned.
+//
+string::size_type
+IceInternal::checkQuote(const string& s, string::size_type start)
+{
+ string::value_type quoteChar = s[start];
+ if(quoteChar == '"' || quoteChar == '\'')
+ {
+ start++;
+ string::size_type pos;
+ while(start < s.size() && (pos = s.find(quoteChar, start)) != string::npos)
+ {
+ if(s[pos - 1] != '\\')
+ {
+ return pos;
+ }
+ start = pos + 1;
+ }
+ return string::npos; // Unmatched quote
+ }
+ return 0; // Not quoted
+}