+String String::escape()
+{
+ const int BUFSIZE = 500;
+
+ char buffer[BUFSIZE];
+ String escaped = "";
+ int i; // Index in buffer[]
+ int j; // Index in *this
+
+ i = 0;
+ for (j = 0; p->s[j] != '\0'; j++)
+ {
+ if (i + 5 > BUFSIZE)
+ {
+ escaped += buffer;
+ i = 0;
+ }
+
+ switch (p->s[j])
+ {
+ case '\a':
+ buffer[i++] = '\\';
+ buffer[i++] = 'a';
+ break;
+
+ case '\b':
+ buffer[i++] = '\\';
+ buffer[i++] = 'b';
+ break;
+
+ case '\f':
+ buffer[i++] = '\\';
+ buffer[i++] = 'f';
+ break;
+
+ case '\n':
+ buffer[i++] = '\\';
+ buffer[i++] = 'n';
+ break;
+
+ case '\r':
+ buffer[i++] = '\\';
+ buffer[i++] = 'r';
+ break;
+
+ case '\t':
+ buffer[i++] = '\\';
+ buffer[i++] = 't';
+ break;
+
+ case '\v':
+ buffer[i++] = '\\';
+ buffer[i++] = 'v';
+ break;
+
+ case '\'':
+ buffer[i++] = '\\';
+ buffer[i++] = '\'';
+ break;
+
+ case '"':
+ buffer[i++] = '\\';
+ buffer[i++] = '"';
+ break;
+
+ case '\\':
+ buffer[i++] = '\\';
+ buffer[i++] = '\\';
+ break;
+
+ default:
+ if (p->s[j] > '\x20' && p->s[j] < '\x7F')
+ {
+ buffer[i++] = p->s[j];
+ }
+ else
+ {
+ short nibble;
+
+ // Turn into hexadecimal representation
+
+ buffer[i++] = '\\';
+ buffer[i++] = 'x';
+ nibble = (p->s[j] >> 4) & 0x0f;
+ buffer[i++] = nibble < 10 ? nibble + '0' : nibble - 10 + 'A';
+ nibble = p->s[j] & 0x0f;
+ buffer[i++] = nibble < 10 ? nibble + '0' : nibble - 10 + 'A';
+ }
+ break;
+ }
+ }
+
+ buffer[i] = '\0';
+ escaped += buffer;
+
+ return escaped;
+}
+
+String String::unescape()
+{
+ String unescaped;
+ char *s, *d;
+
+ unescaped.p->s = new char[strlen(p->s)+1];
+ s = p->s;
+ d = unescaped.p->s;
+
+ while (*s != '\0')
+ {
+ if (*s == '\\')
+ {
+ s++;
+
+ switch (*s)
+ {
+ case 'a':
+ *d = '\a';
+ break;
+
+ case 'b':
+ *d = '\b';
+ break;
+
+ case 'f':
+ *d = '\f';
+ break;
+
+ case 'n':
+ *d = '\n';
+ break;
+
+ case 'r':
+ *d = '\r';
+ break;
+
+ case 't':
+ *d = '\t';
+ break;
+
+ case 'v':
+ *d = '\v';
+ break;
+
+ case '\'':
+ *d = '\'';
+ break;
+
+ case '"':
+ *d = '"';
+ break;
+
+ case '\\':
+ *d = '\\';
+ break;
+
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ *d = 0;
+ while (*s >= '0' && *s <= '7')
+ {
+ *d *= 8;
+ *d += *s - '0';
+ s++;
+ }
+ s--;
+ break;
+
+ case 'x':
+ *d = 0;
+ s++; // Skip the initial 'x'
+ while (isxdigit(*s))
+ {
+ *d *= 16;
+ *d += *s > '9' ? toupper(*s) - 'A' + 10 : *s - '0';
+ s++;
+ }
+ s--;
+ break;
+
+ default:
+ *d = *s;
+ break;
+ }
+ }
+ else
+ {
+ *d = *s;
+ }
+ s++;
+ d++;
+ }
+
+ return unescaped;
+}
+
+