-
Notifications
You must be signed in to change notification settings - Fork 57
Expand file tree
/
Copy pathJsonElement.m
More file actions
248 lines (214 loc) · 8.06 KB
/
JsonElement.m
File metadata and controls
248 lines (214 loc) · 8.06 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
//
// JsonElement.m
// VisualJSON
//
// Created by youknowone on 11. 12. 12..
// Copyright (c) 2011 youknowone.org. All rights reserved.
//
#import "JsonElement.h"
@interface JsonElement ()
// internal data form
- (id)initWithDictionary:(NSDictionary *)dictionary;
- (id)initWithArray:(NSArray *)array;
- (id)initWithTerminal:(id)object;
//! @breif 'Text' view string representation
- (NSString *)descriptionWithDepth:(NSInteger)depth;
@end
//! @brief 'Tree' view internal representation
@interface JsonElement (OutlineDescription)
- (NSString *)outlineItemDescription:(id)item;
- (NSString *)outlineArrayItems;
- (NSString *)outlineDictionaryItems;
@end
@interface NSNumber (JsonElement)
- (NSString *)jsonRepresentation;
@end
@implementation NSNumber (JsonElement)
- (NSString *)jsonRepresentation {
if ([self.className isEqualToString:@"__NSCFBoolean"]) {
return [self boolValue] ? @"true" : @"false";
}
return [self typeFormedDescription];
}
@end
@implementation JsonElement
@synthesize parent=_parent;
@synthesize key=_key, keys=_keys, object=_object, children=_children;
NSDictionary *JsonElementInitializers = nil;
- (id)initWithObject:(id)object {
if ([object isKindOfClass:[NSDictionary class]]) {
return [self initWithDictionary:object];
}
if ([object isKindOfClass:[NSArray class]]) {
return [self initWithArray:object];
}
return [self initWithTerminal:object];
}
+ (id)elementWithObject:(id)object {
return [[[self alloc] initWithObject:object] autorelease];
}
- (id)initWithDictionary:(NSDictionary *)object {
self = [super init];
if (self != nil) {
self.object = object;
self.keys = [object.allKeys sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];
}
return self;
}
- (id)initWithArray:(NSArray *)object {
self = [super init];
if (self != nil) {
self.object = object;
NSMutableArray *keys = [NSMutableArray array];
for (NSInteger i = 0; i < object.count; i++) {
[keys addObject:[NSNumber numberWithInteger:i]];
}
self.keys = [NSArray arrayWithArray:keys];
}
return self;
}
- (id)initWithTerminal:(id)object {
self = [super init];
if (self != nil) {
self.object = object;
}
return self;
}
- (void)dealloc {
self.parent = nil;
self.object = nil;
self.key = nil;
self.keys = nil;
self.children = nil;
[super dealloc];
}
- (id)childAtIndex:(NSInteger)index {
if (self.keys == nil) return nil;
if (self.children == nil) self.children = [NSMutableDictionary dictionary];
id key = [self.keys objectAtIndex:index];
JsonElement *child = [self.children objectForKey:key];
if (child == nil) {
id json = [key isKindOfClass:[NSNumber class]] ? [self.object objectAtIndex:[key integerValue]] : [self.object objectForKey:key];
child = [[self class] elementWithObject:json];
child.parent = self;
child.key = key;
[self.children setObject:child forKey:key];
}
return child;
}
- (NSString *)outlineDescription {
NSString *result = nil;
if (self.keys == nil) {
if ([self.object isKindOfClass:[NSNumber class]]) {
result = [self.object jsonRepresentation];
} else if ([self.object isKindOfClass:[NSNull class]]) {
result = @"null";
}
} else {
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
NSNumber *value = [userDefaults objectForKey:@"ShowBriefDescription"];
BOOL breif = value.boolValue;
if ([self.object isKindOfClass:[NSArray class]]) {
if (breif) {
result = [NSString stringWithFormat:@"Array(%lu): [%@]", [self.keys count], [self outlineArrayItems]];
} else {
result = [NSString stringWithFormat:@"Array(%lu)", [self.keys count]];
}
} else if ([self.object isKindOfClass:[NSDictionary class]]) {
if (breif) {
result = [NSString stringWithFormat:@"Dict(%lu): {%@}", [self.keys count], [self outlineDictionaryItems]];
} else {
result = [NSString stringWithFormat:@"Dict(%lu)", [self.keys count]];
}
}
}
if (result == nil) {
result = [self.object description];
}
result = [result stringByReplacingOccurrencesOfString:@"\n" withString:@"⏎ "];
return result;
}
- (NSString *)description {
return [self descriptionWithDepth:0];
}
- (NSString *)descriptionWithDepth:(NSInteger)depth {
if (self.object == nil) return @"";
NSMutableString *indent = [NSMutableString string];
for (NSInteger i = 0; i < depth; i++) {
[indent appendString:@"\t"];
}
NSString *indent2 = [indent stringByAppendingString:@"\t"];
NSMutableString *desc = [NSMutableString string];
if ([self.object isKindOfClass:[NSArray class]]) {
[desc appendString:@"[\n"];
for (NSInteger i = 0; i < self.keys.count; i++) {
[desc appendString:indent2];
NSString *append = [[self childAtIndex:i] descriptionWithDepth:depth + 1];
[desc appendString:append ? append : @"null"];
[desc appendString:@",\n"];
}
NSInteger deleteCount = 1 + (self.keys.count != 0);
[desc deleteCharactersInRange:NSMakeRange(desc.length - deleteCount, deleteCount)];
[desc appendString:@"\n"];
[desc appendString:indent];
[desc appendString:@"]"];
} else if ([self.object isKindOfClass:[NSDictionary class]]) {
[desc appendString:@"{\n"];
for (NSInteger i = 0; i < self.keys.count; i++) {
[desc appendString:indent2];
id desc2 = [NSString stringWithFormat:@"\"%@\": %@", [self.keys objectAtIndex:i], [[self childAtIndex:i] descriptionWithDepth:depth + 1]];
[desc appendString:desc2];
[desc appendString:@",\n"];
}
NSInteger deleteCount = 1 + (self.keys.count != 0);
[desc deleteCharactersInRange:NSMakeRange(desc.length - deleteCount, deleteCount)];
[desc appendString:@"\n"];
[desc appendString:indent];
[desc appendString:@"}"];
} else if ([self.object isKindOfClass:[NSString class]]) {
[desc appendString:@"\""];
[desc appendString:[self.object stringByReplacingOccurrencesOfString:@"\"" withString:@"\\\""]];
[desc appendString:@"\""];
} else if ([self.object isKindOfClass:[NSNumber class]]) {
[desc appendString:[self.object jsonRepresentation]];
} else if ([self.object isKindOfClass:[NSNull class]]) {
[desc appendString:@"null"];
} else {
[desc appendString:[self.object description]];
}
return desc;
}
@end
@implementation JsonElement (OutlineDescription)
- (NSString *)outlineItemDescription:(id)item {
if ([item isKindOfClass:[NSArray class]]) {
return [NSString stringWithFormat:@"Array(%lu)", [item count]];
} else if ([item isKindOfClass:[NSDictionary class]]) {
return [NSString stringWithFormat:@"Dict(%lu)", [[item allKeys] count]];
} else if ([item isKindOfClass:[NSString class]]) {
return [NSString stringWithFormat:@"\"%@\"", [item stringByReplacingOccurrencesOfString:@"\"" withString:@"\\\""]];
} else if ([item isKindOfClass:[NSNumber class]]) {
return [item jsonRepresentation];
} else {
return [item description];
}
}
- (NSString *)outlineArrayItems {
NSArray *item = self.object;
NSMutableArray *children = [NSMutableArray array];
for (NSInteger i = 0; i < item.count; i++) {
NSString *desc = [self outlineItemDescription:[item objectAtIndex:i]];
[children addObject:desc];
}
return [children componentsJoinedByString:@","];
}
- (NSString *)outlineDictionaryItems {
NSDictionary *item = self.object;
NSMutableArray *children = [NSMutableArray array];
for (id key in self.keys) {
NSString *desc = [self outlineItemDescription:[item objectForKey:key]];
[children addObject:[NSString stringWithFormat:@"\"%@\":%@", key, desc]];
}
return [children componentsJoinedByString:@","];
}
@end