~jose-exposito89/ubuntuone-ios-files/social-networking

« back to all changes in this revision

Viewing changes to Dependencies/ShareKit/Submodules/facebook-ios-sdk/src/JSON/SBJsonWriter.m

  • Committer: José Expósito
  • Date: 2012-10-23 15:22:36 UTC
  • Revision ID: jose.exposito89@gmail.com-20121023152236-f2rfafq000ex0vgz
Added support to share links in social networks

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 Copyright (C) 2009 Stig Brautaset. 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
 * Redistributions of source code must retain the above copyright notice, this
 
8
   list of conditions and the following disclaimer.
 
9
 
 
10
 * Redistributions in binary form must reproduce the above copyright notice,
 
11
   this list of conditions and the following disclaimer in the documentation
 
12
   and/or other materials provided with the distribution.
 
13
 
 
14
 * Neither the name of the author nor the names of its contributors may be used
 
15
   to endorse or promote products derived from this software without specific
 
16
   prior written permission.
 
17
 
 
18
 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 
19
 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 
20
 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 
21
 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
 
22
 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 
23
 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 
24
 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 
25
 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 
26
 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 
27
 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
28
 */
 
29
 
 
30
#import "SBJsonWriter.h"
 
31
 
 
32
@interface SBJsonWriter ()
 
33
 
 
34
- (BOOL)appendValue:(id)fragment into:(NSMutableString*)json;
 
35
- (BOOL)appendArray:(NSArray*)fragment into:(NSMutableString*)json;
 
36
- (BOOL)appendDictionary:(NSDictionary*)fragment into:(NSMutableString*)json;
 
37
- (BOOL)appendString:(NSString*)fragment into:(NSMutableString*)json;
 
38
 
 
39
- (NSString*)indent;
 
40
 
 
41
@end
 
42
 
 
43
@implementation SBJsonWriter
 
44
 
 
45
static NSMutableCharacterSet *kEscapeChars;
 
46
 
 
47
+ (void)initialize {
 
48
        kEscapeChars = [[NSMutableCharacterSet characterSetWithRange: NSMakeRange(0,32)] retain];
 
49
        [kEscapeChars addCharactersInString: @"\"\\"];
 
50
}
 
51
 
 
52
 
 
53
@synthesize sortKeys;
 
54
@synthesize humanReadable;
 
55
 
 
56
/**
 
57
 @deprecated This exists in order to provide fragment support in older APIs in one more version.
 
58
 It should be removed in the next major version.
 
59
 */
 
60
- (NSString*)stringWithFragment:(id)value {
 
61
    [self clearErrorTrace];
 
62
    depth = 0;
 
63
    NSMutableString *json = [NSMutableString stringWithCapacity:128];
 
64
    
 
65
    if ([self appendValue:value into:json])
 
66
        return json;
 
67
    
 
68
    return nil;
 
69
}
 
70
 
 
71
 
 
72
- (NSString*)stringWithObject:(id)value {
 
73
    
 
74
    if ([value isKindOfClass:[NSDictionary class]] || [value isKindOfClass:[NSArray class]]) {
 
75
        return [self stringWithFragment:value];
 
76
    }
 
77
    
 
78
    if ([value respondsToSelector:@selector(proxyForJson)]) {
 
79
        NSString *tmp = [self stringWithObject:[value proxyForJson]];
 
80
        if (tmp)
 
81
            return tmp;
 
82
    }
 
83
        
 
84
 
 
85
    [self clearErrorTrace];
 
86
    [self addErrorWithCode:EFRAGMENT description:@"Not valid type for JSON"];
 
87
    return nil;
 
88
}
 
89
 
 
90
 
 
91
- (NSString*)indent {
 
92
    return [@"\n" stringByPaddingToLength:1 + 2 * depth withString:@" " startingAtIndex:0];
 
93
}
 
94
 
 
95
- (BOOL)appendValue:(id)fragment into:(NSMutableString*)json {
 
96
    if ([fragment isKindOfClass:[NSDictionary class]]) {
 
97
        if (![self appendDictionary:fragment into:json])
 
98
            return NO;
 
99
        
 
100
    } else if ([fragment isKindOfClass:[NSArray class]]) {
 
101
        if (![self appendArray:fragment into:json])
 
102
            return NO;
 
103
        
 
104
    } else if ([fragment isKindOfClass:[NSString class]]) {
 
105
        if (![self appendString:fragment into:json])
 
106
            return NO;
 
107
        
 
108
    } else if ([fragment isKindOfClass:[NSNumber class]]) {
 
109
        if ('c' == *[fragment objCType])
 
110
            [json appendString:[fragment boolValue] ? @"true" : @"false"];
 
111
        else
 
112
            [json appendString:[fragment stringValue]];
 
113
        
 
114
    } else if ([fragment isKindOfClass:[NSNull class]]) {
 
115
        [json appendString:@"null"];
 
116
    } else if ([fragment respondsToSelector:@selector(proxyForJson)]) {
 
117
        [self appendValue:[fragment proxyForJson] into:json];
 
118
        
 
119
    } else {
 
120
        [self addErrorWithCode:EUNSUPPORTED description:[NSString stringWithFormat:@"JSON serialisation not supported for %@", [fragment class]]];
 
121
        return NO;
 
122
    }
 
123
    return YES;
 
124
}
 
125
 
 
126
- (BOOL)appendArray:(NSArray*)fragment into:(NSMutableString*)json {
 
127
    if (maxDepth && ++depth > maxDepth) {
 
128
        [self addErrorWithCode:EDEPTH description: @"Nested too deep"];
 
129
        return NO;
 
130
    }
 
131
    [json appendString:@"["];
 
132
    
 
133
    BOOL addComma = NO;    
 
134
    for (id value in fragment) {
 
135
        if (addComma)
 
136
            [json appendString:@","];
 
137
        else
 
138
            addComma = YES;
 
139
        
 
140
        if ([self humanReadable])
 
141
            [json appendString:[self indent]];
 
142
        
 
143
        if (![self appendValue:value into:json]) {
 
144
            return NO;
 
145
        }
 
146
    }
 
147
    
 
148
    depth--;
 
149
    if ([self humanReadable] && [fragment count])
 
150
        [json appendString:[self indent]];
 
151
    [json appendString:@"]"];
 
152
    return YES;
 
153
}
 
154
 
 
155
- (BOOL)appendDictionary:(NSDictionary*)fragment into:(NSMutableString*)json {
 
156
    if (maxDepth && ++depth > maxDepth) {
 
157
        [self addErrorWithCode:EDEPTH description: @"Nested too deep"];
 
158
        return NO;
 
159
    }
 
160
    [json appendString:@"{"];
 
161
    
 
162
    NSString *colon = [self humanReadable] ? @" : " : @":";
 
163
    BOOL addComma = NO;
 
164
    NSArray *keys = [fragment allKeys];
 
165
    if (self.sortKeys)
 
166
        keys = [keys sortedArrayUsingSelector:@selector(compare:)];
 
167
    
 
168
    for (id value in keys) {
 
169
        if (addComma)
 
170
            [json appendString:@","];
 
171
        else
 
172
            addComma = YES;
 
173
        
 
174
        if ([self humanReadable])
 
175
            [json appendString:[self indent]];
 
176
        
 
177
        if (![value isKindOfClass:[NSString class]]) {
 
178
            [self addErrorWithCode:EUNSUPPORTED description: @"JSON object key must be string"];
 
179
            return NO;
 
180
        }
 
181
        
 
182
        if (![self appendString:value into:json])
 
183
            return NO;
 
184
        
 
185
        [json appendString:colon];
 
186
        if (![self appendValue:[fragment objectForKey:value] into:json]) {
 
187
            [self addErrorWithCode:EUNSUPPORTED description:[NSString stringWithFormat:@"Unsupported value for key %@ in object", value]];
 
188
            return NO;
 
189
        }
 
190
    }
 
191
    
 
192
    depth--;
 
193
    if ([self humanReadable] && [fragment count])
 
194
        [json appendString:[self indent]];
 
195
    [json appendString:@"}"];
 
196
    return YES;    
 
197
}
 
198
 
 
199
- (BOOL)appendString:(NSString*)fragment into:(NSMutableString*)json {
 
200
    
 
201
    [json appendString:@"\""];
 
202
    
 
203
    NSRange esc = [fragment rangeOfCharacterFromSet:kEscapeChars];
 
204
    if ( !esc.length ) {
 
205
        // No special chars -- can just add the raw string:
 
206
        [json appendString:fragment];
 
207
        
 
208
    } else {
 
209
        NSUInteger length = [fragment length];
 
210
        for (NSUInteger i = 0; i < length; i++) {
 
211
            unichar uc = [fragment characterAtIndex:i];
 
212
            switch (uc) {
 
213
                case '"':   [json appendString:@"\\\""];       break;
 
214
                case '\\':  [json appendString:@"\\\\"];       break;
 
215
                case '\t':  [json appendString:@"\\t"];        break;
 
216
                case '\n':  [json appendString:@"\\n"];        break;
 
217
                case '\r':  [json appendString:@"\\r"];        break;
 
218
                case '\b':  [json appendString:@"\\b"];        break;
 
219
                case '\f':  [json appendString:@"\\f"];        break;
 
220
                default:    
 
221
                    if (uc < 0x20) {
 
222
                        [json appendFormat:@"\\u%04x", uc];
 
223
                    } else {
 
224
                        CFStringAppendCharacters((CFMutableStringRef)json, &uc, 1);
 
225
                    }
 
226
                    break;
 
227
                    
 
228
            }
 
229
        }
 
230
    }
 
231
    
 
232
    [json appendString:@"\""];
 
233
    return YES;
 
234
}
 
235
 
 
236
 
 
237
@end