2 Copyright (C) 2000-2005 SKYRIX Software AG
4 This file is part of SOPE.
6 SOPE is free software; you can redistribute it and/or modify it under
7 the terms of the GNU Lesser General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 SOPE is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
14 License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with SOPE; see the file COPYING. If not, write to the
18 Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
22 #include <NGObjWeb/NSString+JavaScriptEscaping.h>
25 @implementation NSString(JavascriptEscaping)
27 static inline unichar HEX_NIBBLE(unichar v) {
28 return (v > 9) ? (v - 10 + 'a') : (v + '0');
31 - (NSString *)stringByApplyingJavaScriptEscaping {
32 /* Replaces \b, \f, \n, \r, \t, ', " by \-escaped sequences.
33 Replaces non-ASCII characters by either \xXX escape sequences,
34 when character is in ISOLatin1, or \uXXXX escape sequences.
35 Result string can be used safely as a Javascript string value.
37 NSString *javascriptEscapedString = self;
38 unsigned additionalCharCount = 0;
39 unsigned length = [self length];
40 int i, firstEscapedCharIndex = -1, lastEscapedCharIndex = length;
42 for(i = length - 1; i >= 0; i -=1) {
43 unichar aChar = [self characterAtIndex:i];
46 additionalCharCount += 5; // \uXXXX
47 firstEscapedCharIndex = i;
49 else if (aChar > 127) {
50 additionalCharCount += 3; // \xXX
51 firstEscapedCharIndex = i;
53 else if (aChar == '\b' || aChar == '\f' || aChar == '\n' ||
55 aChar == '\t' || aChar == '\'' || aChar == '"' || aChar == '\\') {
56 additionalCharCount += 1;
57 firstEscapedCharIndex = i;
59 if (lastEscapedCharIndex == length && additionalCharCount != 0)
60 lastEscapedCharIndex = i;
63 if (additionalCharCount > 0) {
64 unsigned newLength = length + additionalCharCount;
65 unichar *newChars = NSZoneMalloc(NSDefaultMallocZone(),
66 sizeof(unichar) * newLength);
69 [self getCharacters:newChars range:NSMakeRange(0, firstEscapedCharIndex)];
70 for(i = firstEscapedCharIndex; i <= lastEscapedCharIndex; i += 1) {
71 unichar aChar = [self characterAtIndex:i];
74 newChars[i + offset] = '\\';
75 newChars[i + offset + 1] = 'u';
76 newChars[i + offset + 2] = HEX_NIBBLE((aChar >> 12) & 0x0F);
77 newChars[i + offset + 3] = HEX_NIBBLE((aChar >> 8) & 0x0F);
78 newChars[i + offset + 4] = HEX_NIBBLE((aChar >> 4) & 0x0F);
79 newChars[i + offset + 5] = HEX_NIBBLE( aChar & 0x0F);
82 else if (aChar > 127) {
83 newChars[i + offset] = '\\';
84 newChars[i + offset + 1] = 'x';
85 newChars[i + offset + 2] = HEX_NIBBLE((aChar >> 4) & 0x0F);
86 newChars[i + offset + 3] = HEX_NIBBLE( aChar & 0x0F);
89 else if (aChar == '\b') {
90 newChars[i + offset] = '\\';
91 newChars[i + offset + 1] = 'b';
94 else if (aChar == '\f') {
95 newChars[i + offset] = '\\';
96 newChars[i + offset + 1] = 'f';
99 else if (aChar == '\n') {
100 newChars[i + offset] = '\\';
101 newChars[i + offset + 1] = 'n';
104 else if (aChar == '\r') {
105 newChars[i + offset] = '\\';
106 newChars[i + offset + 1] = 'r';
109 else if (aChar == '\t') {
110 newChars[i + offset] = '\\';
111 newChars[i + offset + 1] = 't';
114 else if (aChar == '\'') {
115 newChars[i + offset] = '\\';
116 newChars[i + offset + 1] = '\'';
119 else if (aChar == '"') {
120 newChars[i + offset] = '\\';
121 newChars[i + offset + 1] = '"';
124 else if (aChar == '\\') {
125 newChars[i + offset] = '\\';
126 newChars[i + offset + 1] = '\\';
130 newChars[i + offset] = aChar;
132 if (lastEscapedCharIndex < length)
133 [self getCharacters:(newChars + offset + lastEscapedCharIndex + 1)
134 range:NSMakeRange(lastEscapedCharIndex + 1,
135 length - lastEscapedCharIndex - 1)];
136 javascriptEscapedString = [NSString stringWithCharacters:newChars
140 return javascriptEscapedString;
143 @end /* NSString(JavascriptEscaping) */