]> err.no Git - sope/blob - sope-core/NGExtensions/FdExt.subproj/NSString+Escaping.m
Drop apache 1 build-dependency
[sope] / sope-core / NGExtensions / FdExt.subproj / NSString+Escaping.m
1 /*
2   Copyright (C) 2000-2008 SKYRIX Software AG
3   Copyright (C) 2008      Helge Hess
4
5   This file is part of SOPE.
6
7   SOPE is free software; you can redistribute it and/or modify it under
8   the terms of the GNU Lesser General Public License as published by the
9   Free Software Foundation; either version 2, or (at your option) any
10   later version.
11
12   SOPE is distributed in the hope that it will be useful, but WITHOUT ANY
13   WARRANTY; without even the implied warranty of MERCHANTABILITY or
14   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
15   License for more details.
16
17   You should have received a copy of the GNU Lesser General Public
18   License along with SOPE; see the file COPYING.  If not, write to the
19   Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20   02111-1307, USA.
21 */
22
23 #include <NGExtensions/NSString+Escaping.h>
24 #include "common.h"
25
26 @implementation NSString(Escaping)
27
28 - (NSString *)stringByApplyingCEscaping {
29   // Unicode!
30   unichar  *src;
31   unichar  *buffer;
32   int      len, pos, srcIdx;
33   NSString *s;
34   
35   if ((len = [self length]) == 0)
36     return @"";
37   
38   src = malloc(sizeof(unichar) * (len + 2));
39   [self getCharacters:src];
40   src[len] = 0; // zero-terminate
41   
42   buffer = malloc(sizeof(unichar) * ((len * 2) + 1));
43   
44   for (pos = 0, srcIdx = 0; srcIdx < len; pos++, srcIdx++) {
45     switch (src[srcIdx]) {
46       case '\n':
47         buffer[pos] = '\\'; pos++;
48         buffer[pos] = 'n';
49         break;
50       case '\r':
51         buffer[pos] = '\\'; pos++;
52         buffer[pos] = 'r';
53         break;
54       case '\t':
55         buffer[pos] = '\\'; pos++;
56         buffer[pos] = 't';
57         break;
58         
59       default:
60         buffer[pos] = src[srcIdx];
61         break;
62     }
63   }
64   buffer[pos] = '\0';
65   
66   s = [NSString stringWithCharacters:buffer length:pos];
67   
68   if (buffer != NULL) { free(buffer); buffer = NULL; }
69   if (src    != NULL) { free(src);    src    = NULL; }
70   return s;
71 }
72
73 - (NSString *)stringByEscapingCharactersFromSet:(NSCharacterSet *)_escSet
74   usingStringEscaping:(<NGStringEscaping>)_esc
75 {
76   NSMutableString *safeString;
77   unsigned length;
78   NSRange  prevRange, escRange;
79   NSRange  todoRange;
80   BOOL     needsEscaping;
81   
82   length    = [self length];
83   prevRange = NSMakeRange(0, length);
84   escRange  = [self rangeOfCharacterFromSet:_escSet options:0 range:prevRange];
85
86   needsEscaping = escRange.length > 0 ? YES : NO;
87   if (!needsEscaping)
88     return self; /* cheap */
89   
90   safeString = [NSMutableString stringWithCapacity:length];
91
92   do {
93     NSString *s;
94
95     prevRange.length = escRange.location - prevRange.location;
96     if (prevRange.length > 0)
97       [safeString appendString:[self substringWithRange:prevRange]];
98     
99     s = [_esc stringByEscapingString:[self substringWithRange:escRange]];
100     if (s != nil)
101         [safeString appendString:s];
102
103     prevRange.location = NSMaxRange(escRange);
104     todoRange.location = prevRange.location;
105     todoRange.length   = length - prevRange.location;
106     escRange           = [self rangeOfCharacterFromSet:_escSet
107                                options:0
108                                                  range:todoRange];
109   }
110   while(escRange.length > 0);
111   
112   if (todoRange.length > 0)
113     [safeString appendString:[self substringWithRange:todoRange]];
114   
115   return safeString;
116 }
117
118 @end /* NSString(Escaping) */