├── .DS_Store
├── .gitignore
├── PSGoogleReader.xcodeproj
├── project.pbxproj
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcuserdata
│ │ ├── danielair.xcuserdatad
│ │ └── UserInterfaceState.xcuserstate
│ │ └── isenhower.xcuserdatad
│ │ ├── UserInterfaceState.xcuserstate
│ │ └── WorkspaceSettings.xcsettings
└── xcuserdata
│ ├── danielair.xcuserdatad
│ └── xcschemes
│ │ ├── PSGoogleReader.xcscheme
│ │ └── xcschememanagement.plist
│ └── isenhower.xcuserdatad
│ ├── xcdebugger
│ └── Breakpoints.xcbkptlist
│ └── xcschemes
│ ├── PSGoogleReader.xcscheme
│ └── xcschememanagement.plist
├── PSGoogleReader
├── DetailViewController.h
├── DetailViewController.m
├── GTMDefines.h
├── GTMNSString+HTML.h
├── GTMNSString+HTML.m
├── PSGoogleReader-Info.plist
├── PSGoogleReader-Prefix.pch
├── PSGoogleReader.h
├── PSGoogleReader.m
├── PSGoogleReaderAppDelegate.h
├── PSGoogleReaderAppDelegate.m
├── README
├── RegexKitLite.h
├── RegexKitLite.m
├── RootViewController.h
├── RootViewController.m
├── SBJSON
│ ├── .svn
│ │ ├── all-wcprops
│ │ ├── entries
│ │ └── text-base
│ │ │ ├── JSON.h.svn-base
│ │ │ ├── NSObject+SBJSON.h.svn-base
│ │ │ ├── NSObject+SBJSON.m.svn-base
│ │ │ ├── NSString+SBJSON.h.svn-base
│ │ │ ├── NSString+SBJSON.m.svn-base
│ │ │ ├── SBJSON.h.svn-base
│ │ │ ├── SBJSON.m.svn-base
│ │ │ ├── SBJsonBase.h.svn-base
│ │ │ ├── SBJsonBase.m.svn-base
│ │ │ ├── SBJsonParser.h.svn-base
│ │ │ ├── SBJsonParser.m.svn-base
│ │ │ ├── SBJsonWriter.h.svn-base
│ │ │ └── SBJsonWriter.m.svn-base
│ ├── NSObject+SBJson.h
│ ├── NSObject+SBJson.m
│ ├── SBJson.h
│ ├── SBJsonParser.h
│ ├── SBJsonParser.m
│ ├── SBJsonStreamParser.h
│ ├── SBJsonStreamParser.m
│ ├── SBJsonStreamParserAccumulator.h
│ ├── SBJsonStreamParserAccumulator.m
│ ├── SBJsonStreamParserState.h
│ ├── SBJsonStreamParserState.m
│ ├── SBJsonStreamWriter.h
│ ├── SBJsonStreamWriter.m
│ ├── SBJsonStreamWriterAccumulator.h
│ ├── SBJsonStreamWriterAccumulator.m
│ ├── SBJsonStreamWriterState.h
│ ├── SBJsonStreamWriterState.m
│ ├── SBJsonTokeniser.h
│ ├── SBJsonTokeniser.m
│ ├── SBJsonUTF8Stream.h
│ ├── SBJsonUTF8Stream.m
│ ├── SBJsonWriter.h
│ └── SBJsonWriter.m
├── en.lproj
│ ├── DetailView.xib
│ ├── InfoPlist.strings
│ └── MainWindow.xib
└── main.m
└── README
/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/perspecdev/PSGoogleReader/c2cb32bb3befd78f165dd3a8320a54ffc501c3bf/.DS_Store
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 |
--------------------------------------------------------------------------------
/PSGoogleReader.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/PSGoogleReader.xcodeproj/project.xcworkspace/xcuserdata/isenhower.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/perspecdev/PSGoogleReader/c2cb32bb3befd78f165dd3a8320a54ffc501c3bf/PSGoogleReader.xcodeproj/project.xcworkspace/xcuserdata/isenhower.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/PSGoogleReader.xcodeproj/project.xcworkspace/xcuserdata/isenhower.xcuserdatad/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEWorkspaceUserSettings_HasAskedToTakeAutomaticSnapshotBeforeSignificantChanges
6 |
7 | IDEWorkspaceUserSettings_SnapshotAutomaticallyBeforeSignificantChanges
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/PSGoogleReader.xcodeproj/xcuserdata/danielair.xcuserdatad/xcschemes/PSGoogleReader.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
4 |
7 |
8 |
14 |
20 |
21 |
22 |
23 |
24 |
29 |
30 |
31 |
32 |
40 |
41 |
47 |
48 |
49 |
50 |
51 |
52 |
59 |
60 |
66 |
67 |
68 |
69 |
71 |
72 |
75 |
76 |
77 |
--------------------------------------------------------------------------------
/PSGoogleReader.xcodeproj/xcuserdata/danielair.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | PSGoogleReader.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | 34295800138BB27D00F8352F
16 |
17 | primary
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/PSGoogleReader.xcodeproj/xcuserdata/isenhower.xcuserdatad/xcdebugger/Breakpoints.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
--------------------------------------------------------------------------------
/PSGoogleReader.xcodeproj/xcuserdata/isenhower.xcuserdatad/xcschemes/PSGoogleReader.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
4 |
7 |
8 |
14 |
20 |
21 |
22 |
23 |
24 |
29 |
30 |
31 |
32 |
38 |
39 |
40 |
41 |
49 |
50 |
56 |
57 |
58 |
59 |
60 |
61 |
67 |
68 |
74 |
75 |
76 |
77 |
79 |
80 |
83 |
84 |
85 |
--------------------------------------------------------------------------------
/PSGoogleReader.xcodeproj/xcuserdata/isenhower.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | PSGoogleReader.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | 34295800138BB27D00F8352F
16 |
17 | primary
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/PSGoogleReader/DetailViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // DetailViewController.h
3 | // PSGoogleReader
4 | //
5 | // Created by Daniel Isenhower ( daniel@perspecdev.com ).
6 | // Copyright 2011 PerspecDev Solutions, LLC. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface DetailViewController : UIViewController {
12 |
13 | }
14 |
15 |
16 | @property (nonatomic, retain) IBOutlet UIToolbar *toolbar;
17 |
18 | @property (nonatomic, retain) id detailItem;
19 |
20 | @property (nonatomic, retain) IBOutlet UILabel *detailDescriptionLabel;
21 |
22 | @end
23 |
--------------------------------------------------------------------------------
/PSGoogleReader/DetailViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // DetailViewController.m
3 | // PSGoogleReader
4 | //
5 | // Created by Daniel Isenhower ( daniel@perspecdev.com ).
6 | // Copyright 2011 PerspecDev Solutions, LLC. All rights reserved.
7 | //
8 |
9 | #import "DetailViewController.h"
10 |
11 | #import "RootViewController.h"
12 |
13 | @interface DetailViewController ()
14 | @property (nonatomic, strong) UIPopoverController *popoverController;
15 | - (void)configureView;
16 | @end
17 |
18 | @implementation DetailViewController
19 |
20 | @synthesize toolbar=_toolbar;
21 |
22 | @synthesize detailItem=_detailItem;
23 |
24 | @synthesize detailDescriptionLabel=_detailDescriptionLabel;
25 |
26 | @synthesize popoverController=_myPopoverController;
27 |
28 | #pragma mark - Managing the detail item
29 |
30 | /*
31 | When setting the detail item, update the view and dismiss the popover controller if it's showing.
32 | */
33 | - (void)setDetailItem:(id)newDetailItem
34 | {
35 | if (_detailItem != newDetailItem) {
36 | _detailItem = newDetailItem;
37 |
38 | // Update the view.
39 | [self configureView];
40 | }
41 |
42 | if (self.popoverController != nil) {
43 | [self.popoverController dismissPopoverAnimated:YES];
44 | }
45 | }
46 |
47 | - (void)configureView
48 | {
49 | // Update the user interface for the detail item.
50 |
51 | self.detailDescriptionLabel.text = [self.detailItem description];
52 | }
53 |
54 | - (void)viewWillAppear:(BOOL)animated
55 | {
56 | [super viewWillAppear:animated];
57 | }
58 |
59 | - (void)viewDidAppear:(BOOL)animated
60 | {
61 | [super viewDidAppear:animated];
62 | }
63 |
64 | - (void)viewWillDisappear:(BOOL)animated
65 | {
66 | [super viewWillDisappear:animated];
67 | }
68 |
69 | - (void)viewDidDisappear:(BOOL)animated
70 | {
71 | [super viewDidDisappear:animated];
72 | }
73 |
74 | - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
75 | return YES;
76 | }
77 |
78 | #pragma mark - Split view support
79 |
80 | - (void)splitViewController:(UISplitViewController *)svc willHideViewController:(UIViewController *)aViewController withBarButtonItem:(UIBarButtonItem *)barButtonItem forPopoverController: (UIPopoverController *)pc
81 | {
82 | barButtonItem.title = @"Events";
83 | NSMutableArray *items = [[self.toolbar items] mutableCopy];
84 | [items insertObject:barButtonItem atIndex:0];
85 | [self.toolbar setItems:items animated:YES];
86 | self.popoverController = pc;
87 | }
88 |
89 | // Called when the view is shown again in the split view, invalidating the button and popover controller.
90 | - (void)splitViewController:(UISplitViewController *)svc willShowViewController:(UIViewController *)aViewController invalidatingBarButtonItem:(UIBarButtonItem *)barButtonItem
91 | {
92 | NSMutableArray *items = [[self.toolbar items] mutableCopy];
93 | [items removeObjectAtIndex:0];
94 | [self.toolbar setItems:items animated:YES];
95 | self.popoverController = nil;
96 | }
97 |
98 | /*
99 | // Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
100 | - (void)viewDidLoad
101 | {
102 | [super viewDidLoad];
103 | }
104 | */
105 |
106 | - (void)viewDidUnload
107 | {
108 | [super viewDidUnload];
109 |
110 | // Release any retained subviews of the main view.
111 | // e.g. self.myOutlet = nil;
112 | self.popoverController = nil;
113 | }
114 |
115 | #pragma mark - Memory management
116 |
117 | - (void)didReceiveMemoryWarning
118 | {
119 | // Releases the view if it doesn't have a superview.
120 | [super didReceiveMemoryWarning];
121 |
122 | // Release any cached data, images, etc that aren't in use.
123 | }
124 |
125 | @end
126 |
--------------------------------------------------------------------------------
/PSGoogleReader/GTMDefines.h:
--------------------------------------------------------------------------------
1 | //
2 | // GTMDefines.h
3 | //
4 | // Copyright 2008 Google Inc.
5 | //
6 | // Licensed under the Apache License, Version 2.0 (the "License"); you may not
7 | // use this file except in compliance with the License. You may obtain a copy
8 | // of the License at
9 | //
10 | // http://www.apache.org/licenses/LICENSE-2.0
11 | //
12 | // Unless required by applicable law or agreed to in writing, software
13 | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15 | // License for the specific language governing permissions and limitations under
16 | // the License.
17 | //
18 |
19 | // ============================================================================
20 |
21 | #include
22 | #include
23 |
24 | #if TARGET_OS_IPHONE
25 | #include
26 | #endif // TARGET_OS_IPHONE
27 |
28 | // Not all MAC_OS_X_VERSION_10_X macros defined in past SDKs
29 | #ifndef MAC_OS_X_VERSION_10_5
30 | #define MAC_OS_X_VERSION_10_5 1050
31 | #endif
32 | #ifndef MAC_OS_X_VERSION_10_6
33 | #define MAC_OS_X_VERSION_10_6 1060
34 | #endif
35 |
36 | // Not all __IPHONE_X macros defined in past SDKs
37 | #ifndef __IPHONE_2_1
38 | #define __IPHONE_2_1 20100
39 | #endif
40 | #ifndef __IPHONE_2_2
41 | #define __IPHONE_2_2 20200
42 | #endif
43 | #ifndef __IPHONE_3_0
44 | #define __IPHONE_3_0 30000
45 | #endif
46 | #ifndef __IPHONE_3_1
47 | #define __IPHONE_3_1 30100
48 | #endif
49 | #ifndef __IPHONE_3_2
50 | #define __IPHONE_3_2 30200
51 | #endif
52 | #ifndef __IPHONE_4_0
53 | #define __IPHONE_4_0 40000
54 | #endif
55 |
56 | // ----------------------------------------------------------------------------
57 | // CPP symbols that can be overridden in a prefix to control how the toolbox
58 | // is compiled.
59 | // ----------------------------------------------------------------------------
60 |
61 |
62 | // By setting the GTM_CONTAINERS_VALIDATION_FAILED_LOG and
63 | // GTM_CONTAINERS_VALIDATION_FAILED_ASSERT macros you can control what happens
64 | // when a validation fails. If you implement your own validators, you may want
65 | // to control their internals using the same macros for consistency.
66 | #ifndef GTM_CONTAINERS_VALIDATION_FAILED_ASSERT
67 | #define GTM_CONTAINERS_VALIDATION_FAILED_ASSERT 0
68 | #endif
69 |
70 | // Give ourselves a consistent way to do inlines. Apple's macros even use
71 | // a few different actual definitions, so we're based off of the foundation
72 | // one.
73 | #if !defined(GTM_INLINE)
74 | #if (defined (__GNUC__) && (__GNUC__ == 4)) || defined (__clang__)
75 | #define GTM_INLINE static __inline__ __attribute__((always_inline))
76 | #else
77 | #define GTM_INLINE static __inline__
78 | #endif
79 | #endif
80 |
81 | // Give ourselves a consistent way of doing externs that links up nicely
82 | // when mixing objc and objc++
83 | #if !defined (GTM_EXTERN)
84 | #if defined __cplusplus
85 | #define GTM_EXTERN extern "C"
86 | #define GTM_EXTERN_C_BEGIN extern "C" {
87 | #define GTM_EXTERN_C_END }
88 | #else
89 | #define GTM_EXTERN extern
90 | #define GTM_EXTERN_C_BEGIN
91 | #define GTM_EXTERN_C_END
92 | #endif
93 | #endif
94 |
95 | // Give ourselves a consistent way of exporting things if we have visibility
96 | // set to hidden.
97 | #if !defined (GTM_EXPORT)
98 | #define GTM_EXPORT __attribute__((visibility("default")))
99 | #endif
100 |
101 | // Give ourselves a consistent way of declaring something as unused. This
102 | // doesn't use __unused because that is only supported in gcc 4.2 and greater.
103 | #if !defined (GTM_UNUSED)
104 | #define GTM_UNUSED(x) ((void)(x))
105 | #endif
106 |
107 | // _GTMDevLog & _GTMDevAssert
108 | //
109 | // _GTMDevLog & _GTMDevAssert are meant to be a very lightweight shell for
110 | // developer level errors. This implementation simply macros to NSLog/NSAssert.
111 | // It is not intended to be a general logging/reporting system.
112 | //
113 | // Please see http://code.google.com/p/google-toolbox-for-mac/wiki/DevLogNAssert
114 | // for a little more background on the usage of these macros.
115 | //
116 | // _GTMDevLog log some error/problem in debug builds
117 | // _GTMDevAssert assert if conditon isn't met w/in a method/function
118 | // in all builds.
119 | //
120 | // To replace this system, just provide different macro definitions in your
121 | // prefix header. Remember, any implementation you provide *must* be thread
122 | // safe since this could be called by anything in what ever situtation it has
123 | // been placed in.
124 | //
125 |
126 | // We only define the simple macros if nothing else has defined this.
127 | #ifndef _GTMDevLog
128 |
129 | #ifdef DEBUG
130 | #define _GTMDevLog(...) NSLog(__VA_ARGS__)
131 | #else
132 | #define _GTMDevLog(...) do { } while (0)
133 | #endif
134 |
135 | #endif // _GTMDevLog
136 |
137 | #ifndef _GTMDevAssert
138 | // we directly invoke the NSAssert handler so we can pass on the varargs
139 | // (NSAssert doesn't have a macro we can use that takes varargs)
140 | #if !defined(NS_BLOCK_ASSERTIONS)
141 | #define _GTMDevAssert(condition, ...) \
142 | do { \
143 | if (!(condition)) { \
144 | [[NSAssertionHandler currentHandler] \
145 | handleFailureInFunction:[NSString stringWithUTF8String:__PRETTY_FUNCTION__] \
146 | file:[NSString stringWithUTF8String:__FILE__] \
147 | lineNumber:__LINE__ \
148 | description:__VA_ARGS__]; \
149 | } \
150 | } while(0)
151 | #else // !defined(NS_BLOCK_ASSERTIONS)
152 | #define _GTMDevAssert(condition, ...) do { } while (0)
153 | #endif // !defined(NS_BLOCK_ASSERTIONS)
154 |
155 | #endif // _GTMDevAssert
156 |
157 | // _GTMCompileAssert
158 | // _GTMCompileAssert is an assert that is meant to fire at compile time if you
159 | // want to check things at compile instead of runtime. For example if you
160 | // want to check that a wchar is 4 bytes instead of 2 you would use
161 | // _GTMCompileAssert(sizeof(wchar_t) == 4, wchar_t_is_4_bytes_on_OS_X)
162 | // Note that the second "arg" is not in quotes, and must be a valid processor
163 | // symbol in it's own right (no spaces, punctuation etc).
164 |
165 | // Wrapping this in an #ifndef allows external groups to define their own
166 | // compile time assert scheme.
167 | #ifndef _GTMCompileAssert
168 | // We got this technique from here:
169 | // http://unixjunkie.blogspot.com/2007/10/better-compile-time-asserts_29.html
170 |
171 | #define _GTMCompileAssertSymbolInner(line, msg) _GTMCOMPILEASSERT ## line ## __ ## msg
172 | #define _GTMCompileAssertSymbol(line, msg) _GTMCompileAssertSymbolInner(line, msg)
173 | #define _GTMCompileAssert(test, msg) \
174 | typedef char _GTMCompileAssertSymbol(__LINE__, msg) [ ((test) ? 1 : -1) ]
175 | #endif // _GTMCompileAssert
176 |
177 | // ----------------------------------------------------------------------------
178 | // CPP symbols defined based on the project settings so the GTM code has
179 | // simple things to test against w/o scattering the knowledge of project
180 | // setting through all the code.
181 | // ----------------------------------------------------------------------------
182 |
183 | // Provide a single constant CPP symbol that all of GTM uses for ifdefing
184 | // iPhone code.
185 | #if TARGET_OS_IPHONE // iPhone SDK
186 | // For iPhone specific stuff
187 | #define GTM_IPHONE_SDK 1
188 | #if TARGET_IPHONE_SIMULATOR
189 | #define GTM_IPHONE_SIMULATOR 1
190 | #else
191 | #define GTM_IPHONE_DEVICE 1
192 | #endif // TARGET_IPHONE_SIMULATOR
193 | // By default, GTM has provided it's own unittesting support, define this
194 | // to use the support provided by Xcode, especially for the Xcode4 support
195 | // for unittesting.
196 | #ifndef GTM_IPHONE_USE_SENTEST
197 | #define GTM_IPHONE_USE_SENTEST 0
198 | #endif
199 | #else
200 | // For MacOS specific stuff
201 | #define GTM_MACOS_SDK 1
202 | #endif
203 |
204 | // Some of our own availability macros
205 | #if GTM_MACOS_SDK
206 | #define GTM_AVAILABLE_ONLY_ON_IPHONE UNAVAILABLE_ATTRIBUTE
207 | #define GTM_AVAILABLE_ONLY_ON_MACOS
208 | #else
209 | #define GTM_AVAILABLE_ONLY_ON_IPHONE
210 | #define GTM_AVAILABLE_ONLY_ON_MACOS UNAVAILABLE_ATTRIBUTE
211 | #endif
212 |
213 | // Provide a symbol to include/exclude extra code for GC support. (This mainly
214 | // just controls the inclusion of finalize methods).
215 | #ifndef GTM_SUPPORT_GC
216 | #if GTM_IPHONE_SDK
217 | // iPhone never needs GC
218 | #define GTM_SUPPORT_GC 0
219 | #else
220 | // We can't find a symbol to tell if GC is supported/required, so best we
221 | // do on Mac targets is include it if we're on 10.5 or later.
222 | #if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
223 | #define GTM_SUPPORT_GC 0
224 | #else
225 | #define GTM_SUPPORT_GC 1
226 | #endif
227 | #endif
228 | #endif
229 |
230 | // To simplify support for 64bit (and Leopard in general), we provide the type
231 | // defines for non Leopard SDKs
232 | #if !(MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
233 | // NSInteger/NSUInteger and Max/Mins
234 | #ifndef NSINTEGER_DEFINED
235 | #if __LP64__ || NS_BUILD_32_LIKE_64
236 | typedef long NSInteger;
237 | typedef unsigned long NSUInteger;
238 | #else
239 | typedef int NSInteger;
240 | typedef unsigned int NSUInteger;
241 | #endif
242 | #define NSIntegerMax LONG_MAX
243 | #define NSIntegerMin LONG_MIN
244 | #define NSUIntegerMax ULONG_MAX
245 | #define NSINTEGER_DEFINED 1
246 | #endif // NSINTEGER_DEFINED
247 | // CGFloat
248 | #ifndef CGFLOAT_DEFINED
249 | #if defined(__LP64__) && __LP64__
250 | // This really is an untested path (64bit on Tiger?)
251 | typedef double CGFloat;
252 | #define CGFLOAT_MIN DBL_MIN
253 | #define CGFLOAT_MAX DBL_MAX
254 | #define CGFLOAT_IS_DOUBLE 1
255 | #else /* !defined(__LP64__) || !__LP64__ */
256 | typedef float CGFloat;
257 | #define CGFLOAT_MIN FLT_MIN
258 | #define CGFLOAT_MAX FLT_MAX
259 | #define CGFLOAT_IS_DOUBLE 0
260 | #endif /* !defined(__LP64__) || !__LP64__ */
261 | #define CGFLOAT_DEFINED 1
262 | #endif // CGFLOAT_DEFINED
263 | #endif // MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
264 |
265 | // Some support for advanced clang static analysis functionality
266 | // See http://clang-analyzer.llvm.org/annotations.html
267 | #ifndef __has_feature // Optional.
268 | #define __has_feature(x) 0 // Compatibility with non-clang compilers.
269 | #endif
270 |
271 | #ifndef NS_RETURNS_RETAINED
272 | #if __has_feature(attribute_ns_returns_retained)
273 | #define NS_RETURNS_RETAINED __attribute__((ns_returns_retained))
274 | #else
275 | #define NS_RETURNS_RETAINED
276 | #endif
277 | #endif
278 |
279 | #ifndef NS_RETURNS_NOT_RETAINED
280 | #if __has_feature(attribute_ns_returns_not_retained)
281 | #define NS_RETURNS_NOT_RETAINED __attribute__((ns_returns_not_retained))
282 | #else
283 | #define NS_RETURNS_NOT_RETAINED
284 | #endif
285 | #endif
286 |
287 | #ifndef CF_RETURNS_RETAINED
288 | #if __has_feature(attribute_cf_returns_retained)
289 | #define CF_RETURNS_RETAINED __attribute__((cf_returns_retained))
290 | #else
291 | #define CF_RETURNS_RETAINED
292 | #endif
293 | #endif
294 |
295 | #ifndef CF_RETURNS_NOT_RETAINED
296 | #if __has_feature(attribute_cf_returns_not_retained)
297 | #define CF_RETURNS_NOT_RETAINED __attribute__((cf_returns_not_retained))
298 | #else
299 | #define CF_RETURNS_NOT_RETAINED
300 | #endif
301 | #endif
302 |
303 | #ifndef NS_CONSUMED
304 | #if __has_feature(attribute_ns_consumed)
305 | #define NS_CONSUMED __attribute__((ns_consumed))
306 | #else
307 | #define NS_CONSUMED
308 | #endif
309 | #endif
310 |
311 | #ifndef CF_CONSUMED
312 | #if __has_feature(attribute_cf_consumed)
313 | #define CF_CONSUMED __attribute__((cf_consumed))
314 | #else
315 | #define CF_CONSUMED
316 | #endif
317 | #endif
318 |
319 | #ifndef NS_CONSUMES_SELF
320 | #if __has_feature(attribute_ns_consumes_self)
321 | #define NS_CONSUMES_SELF __attribute__((ns_consumes_self))
322 | #else
323 | #define NS_CONSUMES_SELF
324 | #endif
325 | #endif
326 |
327 | // Defined on 10.6 and above.
328 | #ifndef NS_FORMAT_ARGUMENT
329 | #define NS_FORMAT_ARGUMENT(A)
330 | #endif
331 |
332 | // Defined on 10.6 and above.
333 | #ifndef NS_FORMAT_FUNCTION
334 | #define NS_FORMAT_FUNCTION(F,A)
335 | #endif
336 |
337 | // Defined on 10.6 and above.
338 | #ifndef CF_FORMAT_ARGUMENT
339 | #define CF_FORMAT_ARGUMENT(A)
340 | #endif
341 |
342 | // Defined on 10.6 and above.
343 | #ifndef CF_FORMAT_FUNCTION
344 | #define CF_FORMAT_FUNCTION(F,A)
345 | #endif
346 |
347 | #ifndef GTM_NONNULL
348 | #define GTM_NONNULL(x) __attribute__((nonnull(x)))
349 | #endif
350 |
351 | #ifdef __OBJC__
352 |
353 | // Declared here so that it can easily be used for logging tracking if
354 | // necessary. See GTMUnitTestDevLog.h for details.
355 | @class NSString;
356 | GTM_EXTERN void _GTMUnitTestDevLog(NSString *format, ...);
357 |
358 | // Macro to allow you to create NSStrings out of other macros.
359 | // #define FOO foo
360 | // NSString *fooString = GTM_NSSTRINGIFY(FOO);
361 | #if !defined (GTM_NSSTRINGIFY)
362 | #define GTM_NSSTRINGIFY_INNER(x) @#x
363 | #define GTM_NSSTRINGIFY(x) GTM_NSSTRINGIFY_INNER(x)
364 | #endif
365 |
366 | // Macro to allow fast enumeration when building for 10.5 or later, and
367 | // reliance on NSEnumerator for 10.4. Remember, NSDictionary w/ FastEnumeration
368 | // does keys, so pick the right thing, nothing is done on the FastEnumeration
369 | // side to be sure you're getting what you wanted.
370 | #ifndef GTM_FOREACH_OBJECT
371 | #if TARGET_OS_IPHONE || !(MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5)
372 | #define GTM_FOREACH_ENUMEREE(element, enumeration) \
373 | for (element in enumeration)
374 | #define GTM_FOREACH_OBJECT(element, collection) \
375 | for (element in collection)
376 | #define GTM_FOREACH_KEY(element, collection) \
377 | for (element in collection)
378 | #else
379 | #define GTM_FOREACH_ENUMEREE(element, enumeration) \
380 | for (NSEnumerator *_ ## element ## _enum = enumeration; \
381 | (element = [_ ## element ## _enum nextObject]) != nil; )
382 | #define GTM_FOREACH_OBJECT(element, collection) \
383 | GTM_FOREACH_ENUMEREE(element, [collection objectEnumerator])
384 | #define GTM_FOREACH_KEY(element, collection) \
385 | GTM_FOREACH_ENUMEREE(element, [collection keyEnumerator])
386 | #endif
387 | #endif
388 |
389 | // ============================================================================
390 |
391 | // To simplify support for both Leopard and Snow Leopard we declare
392 | // the Snow Leopard protocols that we need here.
393 | #if !defined(GTM_10_6_PROTOCOLS_DEFINED) && !(MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6)
394 | #define GTM_10_6_PROTOCOLS_DEFINED 1
395 | @protocol NSConnectionDelegate
396 | @end
397 | @protocol NSAnimationDelegate
398 | @end
399 | @protocol NSImageDelegate
400 | @end
401 | @protocol NSTabViewDelegate
402 | @end
403 | #endif // !defined(GTM_10_6_PROTOCOLS_DEFINED) && !(MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6)
404 |
405 | // GTM_SEL_STRING is for specifying selector (usually property) names to KVC
406 | // or KVO methods.
407 | // In debug it will generate warnings for undeclared selectors if
408 | // -Wunknown-selector is turned on.
409 | // In release it will have no runtime overhead.
410 | #ifndef GTM_SEL_STRING
411 | #ifdef DEBUG
412 | #define GTM_SEL_STRING(selName) NSStringFromSelector(@selector(selName))
413 | #else
414 | #define GTM_SEL_STRING(selName) @#selName
415 | #endif // DEBUG
416 | #endif // GTM_SEL_STRING
417 |
418 | #endif // __OBJC__
--------------------------------------------------------------------------------
/PSGoogleReader/GTMNSString+HTML.h:
--------------------------------------------------------------------------------
1 | //
2 | // GTMNSString+HTML.h
3 | // Dealing with NSStrings that contain HTML
4 | //
5 | // Copyright 2006-2008 Google Inc.
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License"); you may not
8 | // use this file except in compliance with the License. You may obtain a copy
9 | // of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
16 | // License for the specific language governing permissions and limitations under
17 | // the License.
18 | //
19 |
20 | #import
21 |
22 | /// Utilities for NSStrings containing HTML
23 | @interface NSString (GTMNSStringHTMLAdditions)
24 |
25 | /// Get a string where internal characters that need escaping for HTML are escaped
26 | //
27 | /// For example, '&' become '&'. This will only cover characters from table
28 | /// A.2.2 of http://www.w3.org/TR/xhtml1/dtds.html#a_dtd_Special_characters
29 | /// which is what you want for a unicode encoded webpage. If you have a ascii
30 | /// or non-encoded webpage, please use stringByEscapingAsciiHTML which will
31 | /// encode all characters.
32 | ///
33 | /// For obvious reasons this call is only safe once.
34 | //
35 | // Returns:
36 | // Autoreleased NSString
37 | //
38 | - (NSString *)gtm_stringByEscapingForHTML;
39 |
40 | /// Get a string where internal characters that need escaping for HTML are escaped
41 | //
42 | /// For example, '&' become '&'
43 | /// All non-mapped characters (unicode that don't have a &keyword; mapping)
44 | /// will be converted to the appropriate xx; value. If your webpage is
45 | /// unicode encoded (UTF16 or UTF8) use stringByEscapingHTML instead as it is
46 | /// faster, and produces less bloated and more readable HTML (as long as you
47 | /// are using a unicode compliant HTML reader).
48 | ///
49 | /// For obvious reasons this call is only safe once.
50 | //
51 | // Returns:
52 | // Autoreleased NSString
53 | //
54 | - (NSString *)gtm_stringByEscapingForAsciiHTML;
55 |
56 | /// Get a string where internal characters that are escaped for HTML are unescaped
57 | //
58 | /// For example, '&' becomes '&'
59 | /// Handles and 2 cases as well
60 | ///
61 | // Returns:
62 | // Autoreleased NSString
63 | //
64 | - (NSString *)gtm_stringByUnescapingFromHTML;
65 |
66 | @end
--------------------------------------------------------------------------------
/PSGoogleReader/PSGoogleReader-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDisplayName
8 | ${PRODUCT_NAME}
9 | CFBundleExecutable
10 | ${EXECUTABLE_NAME}
11 | CFBundleIconFile
12 |
13 | CFBundleIdentifier
14 | com.perspecdev.${PRODUCT_NAME:rfc1034identifier}
15 | CFBundleInfoDictionaryVersion
16 | 6.0
17 | CFBundleName
18 | ${PRODUCT_NAME}
19 | CFBundlePackageType
20 | APPL
21 | CFBundleShortVersionString
22 | 1.1
23 | CFBundleSignature
24 | ????
25 | CFBundleVersion
26 | 2
27 | LSRequiresIPhoneOS
28 |
29 | NSMainNibFile
30 | MainWindow
31 | UISupportedInterfaceOrientations~ipad
32 |
33 | UIInterfaceOrientationPortrait
34 | UIInterfaceOrientationPortraitUpsideDown
35 | UIInterfaceOrientationLandscapeLeft
36 | UIInterfaceOrientationLandscapeRight
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/PSGoogleReader/PSGoogleReader-Prefix.pch:
--------------------------------------------------------------------------------
1 | //
2 | // Prefix header for all source files of the 'PSGoogleReader' target in the 'PSGoogleReader' project
3 | //
4 |
5 | #import
6 |
7 | #ifndef __IPHONE_3_0
8 | #warning "This project uses features only available in iPhone SDK 3.0 and later."
9 | #endif
10 |
11 | #ifdef __OBJC__
12 | #import
13 | #import
14 | #endif
15 |
--------------------------------------------------------------------------------
/PSGoogleReader/PSGoogleReader.h:
--------------------------------------------------------------------------------
1 | //
2 | // PSGoogleReader.h
3 | // PSGoogleReader
4 | //
5 | // Created by Daniel Isenhower ( daniel@perspecdev.com ).
6 | // Copyright 2011 PerspecDev Solutions, LLC. All rights reserved.
7 | //
8 |
9 | /*
10 | Redistribution and use in source and binary forms, with or without
11 | modification, are permitted provided that the following conditions are met:
12 |
13 | * Redistributions of source code must retain the above copyright notice, this
14 | list of conditions and the following disclaimer.
15 |
16 | * Redistributions in binary form must reproduce the above copyright notice,
17 | this list of conditions and the following disclaimer in the documentation
18 | and/or other materials provided with the distribution.
19 |
20 | * Neither the name of the author nor the names of its contributors may be used
21 | to endorse or promote products derived from this software without specific
22 | prior written permission.
23 |
24 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
28 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
30 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
32 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 | */
35 |
36 | #import
37 |
38 | @class SBJsonParser;
39 |
40 | @protocol PSGoogleReaderDelegate
41 |
42 | - (void)googleReaderIncrementNetworkActivity;
43 | - (void)googleReaderDecrementNetworkActivity;
44 | - (void)googleReaderInitializedAndReady;
45 | - (void)googleReaderNeedsLogin;
46 | - (void)googleReaderReadingListData:(NSArray *)items isLastBatch:(BOOL)isLastBatch;
47 | - (BOOL)googleReaderIsReadyForMoreItems;
48 | - (void)googleReaderReadingListDataWillComplete;
49 | - (void)googleReaderReadingListDataDidComplete;
50 | - (void)googleReaderCouldNotGetReadingList;
51 | - (void)googleReaderSubscriptionList:(NSArray *)aSubscriptionList;
52 | - (void)googleReaderIsReadSynced:(NSString *)itemId;
53 | - (void)googleReaderSubscriptionAdded;
54 | - (void)googleReaderCouldNotAddSubscription;
55 | - (void)googleReaderSubscriptionRemoved;
56 | - (void)googleReaderCouldNotRemoveSubscription;
57 | - (void)googleReaderURLError:(NSError *)error;
58 |
59 | @end
60 |
61 | @interface PSGoogleReader : NSObject {
62 | NSString *SID;
63 | NSTimeInterval lastUpdate;
64 | BOOL gettingReadingList;
65 | id __weak delegate;
66 |
67 | NSString *URLFormatGetSID;
68 | NSString *URLFormatGetToken;
69 | NSString *URLFormatQuickAddFeed;
70 | NSString *URLFormatAddFeed;
71 | NSString *URLFormatEditFeed;
72 | NSString *URLFormatRemoveFeed;
73 | NSString *URLFormatSetFeedLabel;
74 | NSString *URLFormatGetUnreadCount;
75 | NSString *URLFormatGetUserInfo;
76 | NSString *URLFormatGetFeed;
77 | NSString *URLFormatGetLabel;
78 | NSString *URLFormatGetReadingListIds;
79 | NSString *URLFormatGetStarredIds;
80 | NSString *URLFormatGetReadingListContents;
81 | NSString *URLFormatGetSubscriptionList;
82 | NSString *URLFormatGetStarred;
83 | NSString *URLFormatGetBroadcasted;
84 | NSString *URLFormatGetNotes;
85 | NSString *URLFormatAddTag;
86 | NSString *URLFormatRemoveTag;
87 | NSString *URLFormatSetRead;
88 | NSString *URLFormatSetNotRead;
89 | NSString *URLFormatSetFeedRead;
90 | NSString *URLFormatSetStarred;
91 | NSString *URLFormatSetNotStarred;
92 | NSString *URLFormatSetLike;
93 | NSString *URLFormatSetNotLike;
94 | NSString *URLFormatSetBroadcast;
95 | NSString *URLFormatSetNotBroadcast;
96 | NSString *URLFormatEmail;
97 |
98 | NSMutableDictionary *postFields;
99 |
100 | NSString *username;
101 | NSString *password;
102 | NSString *token;
103 | NSString *unixTimeCutoff;
104 | NSString *excludeTarget;
105 | NSString *numResults;
106 | NSString *continuationString;
107 | NSString *client;
108 | NSString *sortOrder;
109 | NSString *itemIdentifier;
110 | NSString *feedURL;
111 | NSString *feedId;
112 | BOOL needsLogin;
113 | BOOL processingItemsToModify;
114 |
115 | NSMutableDictionary *cookieInfo;
116 | NSMutableSet *connections;
117 | NSMutableDictionary *connectionIdentifiers;
118 | NSMutableDictionary *responseData;
119 | NSMutableArray *tokenSelectors;
120 | NSMutableArray *itemsToModify;
121 | SBJsonParser *json;
122 | }
123 |
124 | @property (nonatomic, weak) id delegate;
125 | @property (nonatomic, strong) NSString *SID;
126 | @property (nonatomic, readonly) NSString *username;
127 | @property (nonatomic, readonly) NSString *password;
128 | @property (nonatomic) NSTimeInterval lastUpdate;
129 | @property (nonatomic) BOOL gettingReadingList;
130 |
131 | - (id)init;
132 | - (id)initWithSID:(NSString *)anSID;
133 | - (void)resetForNewRequest;
134 | - (void)setURLFormats;
135 | - (void)loginWithUsername:(NSString *)aUsername withPassword:(NSString *)aPassword;
136 | - (void)logout;
137 | - (void)retrieveTokenWithSelectorName:(NSString *)selectorName;
138 | - (void)retrieveSubscriptionList;
139 | - (void)retrieveUnreadCount;
140 | - (void)retrieveReadingList;
141 | - (void)markAsRead:(NSString *)itemId;
142 | - (void)markAsUnread:(NSString *)itemId;
143 | - (void)markAsStarred:(NSString *)itemId;
144 | - (void)markAsUnstarred:(NSString *)itemId;
145 | - (void)markFeedAsRead:(NSString *)aFeedId;
146 | - (void)quickAddFeed:(NSString *)aFeedURL;
147 | - (void)quickAddFeedFromPresetURL;
148 | - (void)removeFeed:(NSString *)aFeedId;
149 | - (void)removeFeedFromPresetId;
150 | - (void)processItemsToModify;
151 | - (void)rerunActionForConnectionIdentifier:(NSString *)identifier;
152 | - (void)cancelAllConnections;
153 |
154 | @end
--------------------------------------------------------------------------------
/PSGoogleReader/PSGoogleReaderAppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // PSGoogleReaderAppDelegate.h
3 | // PSGoogleReader
4 | //
5 | // Created by Daniel Isenhower ( daniel@perspecdev.com ).
6 | // Copyright 2011 PerspecDev Solutions, LLC. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | #import "PSGoogleReader.h"
12 |
13 | @class RootViewController;
14 |
15 | @class DetailViewController;
16 |
17 | @interface PSGoogleReaderAppDelegate : NSObject {
18 | PSGoogleReader *googleReader;
19 | int networkActivityCounter;
20 | }
21 |
22 | @property (nonatomic, strong) IBOutlet UIWindow *window;
23 |
24 | @property (nonatomic, weak) IBOutlet UISplitViewController *splitViewController;
25 |
26 | @property (nonatomic, weak) IBOutlet RootViewController *rootViewController;
27 |
28 | @property (nonatomic, weak) IBOutlet DetailViewController *detailViewController;
29 |
30 | @end
31 |
--------------------------------------------------------------------------------
/PSGoogleReader/PSGoogleReaderAppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // TODO: Add UITableView, etc to make a cleaner demo UI, rather than just spitting everything out via NSLog
3 | //
4 | // PSGoogleReaderAppDelegate.m
5 | // PSGoogleReader
6 | //
7 | // Created by Daniel Isenhower ( daniel@perspecdev.com ).
8 | // Copyright 2011 PerspecDev Solutions, LLC. All rights reserved.
9 | //
10 |
11 | #import "PSGoogleReaderAppDelegate.h"
12 |
13 | #import "RootViewController.h"
14 |
15 | @implementation PSGoogleReaderAppDelegate
16 |
17 |
18 | @synthesize window=_window;
19 |
20 | @synthesize splitViewController=_splitViewController;
21 |
22 | @synthesize rootViewController=_rootViewController;
23 |
24 | @synthesize detailViewController=_detailViewController;
25 |
26 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
27 | // Override point for customization after application launch.
28 | // Add the split view controller's view to the window and display.
29 | self.window.rootViewController = self.splitViewController;
30 | [self.window makeKeyAndVisible];
31 |
32 | networkActivityCounter = 0;
33 |
34 | NSString *username = @"google-acount-username";
35 | NSString *password = @"google-account-password";
36 | googleReader = [[PSGoogleReader alloc] init];
37 | // you should store googleReader.SID when the googleReaderInitializedAndReady method returns, then
38 | // pass that value to initWithSID: rather than always logging in with the user's username & password
39 | [googleReader loginWithUsername:username withPassword:password];
40 | googleReader.delegate = self; // see below for delegate methods
41 |
42 | return YES;
43 | }
44 |
45 | - (void)applicationWillResignActive:(UIApplication *)application {
46 | /*
47 | Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
48 | Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
49 | */
50 | }
51 |
52 | - (void)applicationDidEnterBackground:(UIApplication *)application {
53 | /*
54 | Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
55 | If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
56 | */
57 | }
58 |
59 | - (void)applicationWillEnterForeground:(UIApplication *)application {
60 | /*
61 | Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
62 | */
63 | }
64 |
65 | - (void)applicationDidBecomeActive:(UIApplication *)application {
66 | /*
67 | Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
68 | */
69 | }
70 |
71 | - (void)applicationWillTerminate:(UIApplication *)application {
72 | /*
73 | Called when the application is about to terminate.
74 | Save data if appropriate.
75 | See also applicationDidEnterBackground:.
76 | */
77 | }
78 |
79 | # pragma mark - PSGoogleReaderDelegate methods
80 |
81 | - (void)googleReaderIncrementNetworkActivity {
82 | if (networkActivityCounter++ == 0) {
83 | [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
84 | }
85 | }
86 |
87 | - (void)googleReaderDecrementNetworkActivity {
88 | if (--networkActivityCounter <= 0) {
89 | [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
90 | networkActivityCounter = 0; // just in case
91 | }
92 | }
93 |
94 | - (void)googleReaderInitializedAndReady {
95 | NSLog(@"PSGoogleReader initialized and ready");
96 | NSLog(@"Retrieving reading list...");
97 | [googleReader retrieveReadingList];
98 | }
99 |
100 | - (void)googleReaderNeedsLogin {
101 | NSLog(@"Google Reader needs login");
102 | }
103 |
104 | - (void)googleReaderReadingListData:(NSArray *)items isLastBatch:(BOOL)isLastBatch {
105 | for (NSDictionary *item in items) {
106 | NSLog(@"%@", [item objectForKey:@"title"]);
107 | }
108 | }
109 |
110 | - (BOOL)googleReaderIsReadyForMoreItems {
111 | return YES;
112 | }
113 |
114 | - (void)googleReaderReadingListDataDidComplete {
115 | NSLog(@"Reading list data complete");
116 | }
117 |
118 | - (void)googleReaderReadingListDataWillComplete {
119 | //
120 | }
121 |
122 | - (void)googleReaderCouldNotGetReadingList {
123 | NSLog(@"Could not get reading list");
124 | }
125 |
126 | - (void)googleReaderSubscriptionList:(NSArray *)aSubscriptionList {
127 | //
128 | }
129 |
130 | - (void)googleReaderIsReadSynced:(NSString *)itemId {
131 | //
132 | }
133 |
134 | - (void)googleReaderSubscriptionAdded {
135 | //
136 | }
137 |
138 | - (void)googleReaderCouldNotAddSubscription {
139 | //
140 | }
141 |
142 | - (void)googleReaderSubscriptionRemoved {
143 | //
144 | }
145 |
146 | - (void)googleReaderCouldNotRemoveSubscription {
147 | //
148 | }
149 |
150 | - (void)googleReaderURLError:(NSError *)error {
151 | NSLog(@"URL Error: %@", [error description]);
152 | }
153 |
154 | @end
155 |
--------------------------------------------------------------------------------
/PSGoogleReader/README:
--------------------------------------------------------------------------------
1 | PSGoogleReader is a class that connects to Google Reader. I don't have a pretty
2 | demo UI set up, so you won't see much in the simulator when you run this app. Check
3 | NSLog output to see very simplified demo results.
4 |
5 | Be sure to set your client (app) name in PSGoogleReader.m
6 | Set your Google Reader username/password in PSGoogleReaderAppDelegate.m
7 |
8 | Code license is pretty generous. See comments at the top of PSGoogleReader.m for details.
9 |
10 | Email me if you have any questions: daniel@perspecdev.com
--------------------------------------------------------------------------------
/PSGoogleReader/RootViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // RootViewController.h
3 | // PSGoogleReader
4 | //
5 | // Created by Daniel Isenhower ( daniel@perspecdev.com ).
6 | // Copyright 2011 PerspecDev Solutions, LLC. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @class DetailViewController;
12 |
13 | @interface RootViewController : UITableViewController {
14 |
15 | }
16 |
17 |
18 | @property (nonatomic, strong) IBOutlet DetailViewController *detailViewController;
19 |
20 | @end
21 |
--------------------------------------------------------------------------------
/PSGoogleReader/RootViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // RootViewController.m
3 | // PSGoogleReader
4 | //
5 | // Created by Daniel Isenhower ( daniel@perspecdev.com ).
6 | // Copyright 2011 PerspecDev Solutions, LLC. All rights reserved.
7 | //
8 |
9 | #import "RootViewController.h"
10 |
11 | #import "DetailViewController.h"
12 |
13 | @implementation RootViewController
14 |
15 | @synthesize detailViewController;
16 |
17 | - (void)viewDidLoad
18 | {
19 | [super viewDidLoad];
20 | self.clearsSelectionOnViewWillAppear = NO;
21 | self.contentSizeForViewInPopover = CGSizeMake(320.0, 600.0);
22 | }
23 |
24 |
25 | - (void)viewWillAppear:(BOOL)animated
26 | {
27 | [super viewWillAppear:animated];
28 | }
29 |
30 | - (void)viewDidAppear:(BOOL)animated
31 | {
32 | [super viewDidAppear:animated];
33 | }
34 |
35 | - (void)viewWillDisappear:(BOOL)animated
36 | {
37 | [super viewWillDisappear:animated];
38 | }
39 |
40 | - (void)viewDidDisappear:(BOOL)animated
41 | {
42 | [super viewDidDisappear:animated];
43 | }
44 |
45 | - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
46 | return YES;
47 | }
48 |
49 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
50 | {
51 | return 1;
52 |
53 | }
54 |
55 |
56 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
57 | {
58 | return 0;
59 |
60 | }
61 |
62 |
63 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
64 | {
65 | static NSString *CellIdentifier = @"Cell";
66 |
67 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
68 | if (cell == nil) {
69 | cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
70 | }
71 |
72 | // Configure the cell.
73 |
74 | return cell;
75 | }
76 |
77 | /*
78 | // Override to support conditional editing of the table view.
79 | - (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
80 | {
81 | // Return NO if you do not want the specified item to be editable.
82 | return YES;
83 | }
84 | */
85 |
86 | /*
87 | // Override to support editing the table view.
88 | - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
89 | {
90 |
91 | if (editingStyle == UITableViewCellEditingStyleDelete) {
92 | // Delete the row from the data source.
93 | [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
94 | }
95 | else if (editingStyle == UITableViewCellEditingStyleInsert) {
96 | // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view.
97 | }
98 | }
99 | */
100 |
101 | /*
102 | // Override to support rearranging the table view.
103 | - (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
104 | {
105 | }
106 | */
107 |
108 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
109 | {
110 | // Navigation logic may go here -- for example, create and push another view controller.
111 | /*
112 | <#DetailViewController#> *detailViewController = [[<#DetailViewController#> alloc] initWithNibName:@"<#Nib name#>" bundle:nil];
113 | NSManagedObject *selectedObject = [[self fetchedResultsController] objectAtIndexPath:indexPath];
114 | // ...
115 | // Pass the selected object to the new view controller.
116 | [self.navigationController pushViewController:detailViewController animated:YES];
117 | [detailViewController release];
118 | */
119 | }
120 |
121 | - (void)didReceiveMemoryWarning
122 | {
123 | // Releases the view if it doesn't have a superview.
124 | [super didReceiveMemoryWarning];
125 |
126 | // Relinquish ownership any cached data, images, etc that aren't in use.
127 | }
128 |
129 | - (void)viewDidUnload
130 | {
131 | // Relinquish ownership of anything that can be recreated in viewDidLoad or on demand.
132 | // For example: self.myOutlet = nil;
133 | }
134 |
135 | @end
136 |
--------------------------------------------------------------------------------
/PSGoogleReader/SBJSON/.svn/all-wcprops:
--------------------------------------------------------------------------------
1 | K 25
2 | svn:wc:ra_dav:version-url
3 | V 44
4 | /newsstand/!svn/ver/4/Newsstand/Classes/JSON
5 | END
6 | JSON.h
7 | K 25
8 | svn:wc:ra_dav:version-url
9 | V 51
10 | /newsstand/!svn/ver/4/Newsstand/Classes/JSON/JSON.h
11 | END
12 | SBJsonBase.h
13 | K 25
14 | svn:wc:ra_dav:version-url
15 | V 57
16 | /newsstand/!svn/ver/4/Newsstand/Classes/JSON/SBJsonBase.h
17 | END
18 | SBJsonParser.h
19 | K 25
20 | svn:wc:ra_dav:version-url
21 | V 59
22 | /newsstand/!svn/ver/4/Newsstand/Classes/JSON/SBJsonParser.h
23 | END
24 | SBJsonWriter.h
25 | K 25
26 | svn:wc:ra_dav:version-url
27 | V 59
28 | /newsstand/!svn/ver/4/Newsstand/Classes/JSON/SBJsonWriter.h
29 | END
30 | SBJSON.h
31 | K 25
32 | svn:wc:ra_dav:version-url
33 | V 53
34 | /newsstand/!svn/ver/4/Newsstand/Classes/JSON/SBJSON.h
35 | END
36 | SBJsonBase.m
37 | K 25
38 | svn:wc:ra_dav:version-url
39 | V 57
40 | /newsstand/!svn/ver/4/Newsstand/Classes/JSON/SBJsonBase.m
41 | END
42 | SBJsonParser.m
43 | K 25
44 | svn:wc:ra_dav:version-url
45 | V 59
46 | /newsstand/!svn/ver/4/Newsstand/Classes/JSON/SBJsonParser.m
47 | END
48 | SBJsonWriter.m
49 | K 25
50 | svn:wc:ra_dav:version-url
51 | V 59
52 | /newsstand/!svn/ver/4/Newsstand/Classes/JSON/SBJsonWriter.m
53 | END
54 | NSObject+SBJSON.h
55 | K 25
56 | svn:wc:ra_dav:version-url
57 | V 62
58 | /newsstand/!svn/ver/4/Newsstand/Classes/JSON/NSObject+SBJSON.h
59 | END
60 | NSString+SBJSON.h
61 | K 25
62 | svn:wc:ra_dav:version-url
63 | V 62
64 | /newsstand/!svn/ver/4/Newsstand/Classes/JSON/NSString+SBJSON.h
65 | END
66 | SBJSON.m
67 | K 25
68 | svn:wc:ra_dav:version-url
69 | V 53
70 | /newsstand/!svn/ver/4/Newsstand/Classes/JSON/SBJSON.m
71 | END
72 | NSObject+SBJSON.m
73 | K 25
74 | svn:wc:ra_dav:version-url
75 | V 62
76 | /newsstand/!svn/ver/4/Newsstand/Classes/JSON/NSObject+SBJSON.m
77 | END
78 | NSString+SBJSON.m
79 | K 25
80 | svn:wc:ra_dav:version-url
81 | V 62
82 | /newsstand/!svn/ver/4/Newsstand/Classes/JSON/NSString+SBJSON.m
83 | END
84 |
--------------------------------------------------------------------------------
/PSGoogleReader/SBJSON/.svn/entries:
--------------------------------------------------------------------------------
1 | 10
2 |
3 | dir
4 | 4
5 | http://daniel@svn.gummydev.com:80/newsstand/Newsstand/Classes/JSON
6 | http://daniel@svn.gummydev.com:80/newsstand
7 |
8 |
9 |
10 | 2010-05-16T16:38:25.051850Z
11 | 4
12 | daniel
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 | 6832bc1b-7a86-0410-95ef-da82e53b28ac
28 |
29 | JSON.h
30 | file
31 |
32 |
33 |
34 |
35 | 2010-05-16T16:12:47.000000Z
36 | ae257619c962a55d5fa93b7825837756
37 | 2010-05-16T16:38:25.051850Z
38 | 4
39 | daniel
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 | 2297
62 |
63 | SBJsonBase.h
64 | file
65 |
66 |
67 |
68 |
69 | 2010-05-16T16:12:47.000000Z
70 | 048b288f47c5a61c084536c82c81f9af
71 | 2010-05-16T16:38:25.051850Z
72 | 4
73 | daniel
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 | 2946
96 |
97 | SBJsonParser.h
98 | file
99 |
100 |
101 |
102 |
103 | 2010-05-16T16:12:47.000000Z
104 | a144e6967ed27047ee00fba36f60b848
105 | 2010-05-16T16:38:25.051850Z
106 | 4
107 | daniel
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 | 3083
130 |
131 | SBJsonWriter.h
132 | file
133 |
134 |
135 |
136 |
137 | 2010-05-16T16:12:47.000000Z
138 | 37d52748720cd2c19cd2cfa16baa6f14
139 | 2010-05-16T16:38:25.051850Z
140 | 4
141 | daniel
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 | 4416
164 |
165 | SBJSON.h
166 | file
167 |
168 |
169 |
170 |
171 | 2010-05-16T16:12:47.000000Z
172 | 23022b462daf29618e033215c58aac94
173 | 2010-05-16T16:38:25.051850Z
174 | 4
175 | daniel
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 | 2797
198 |
199 | SBJsonBase.m
200 | file
201 |
202 |
203 |
204 |
205 | 2010-05-16T16:12:47.000000Z
206 | 4885652fed0a995c1aff1cf47c15117c
207 | 2010-05-16T16:38:25.051850Z
208 | 4
209 | daniel
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 | 2753
232 |
233 | SBJsonParser.m
234 | file
235 |
236 |
237 |
238 |
239 | 2010-05-16T16:12:47.000000Z
240 | 9dac8ca97a24ae84b56fc9ede4651d5c
241 | 2010-05-16T16:38:25.051850Z
242 | 4
243 | daniel
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
265 | 14032
266 |
267 | SBJsonWriter.m
268 | file
269 |
270 |
271 |
272 |
273 | 2010-05-16T16:12:47.000000Z
274 | 92548eb6ea5c890522c2d342b41d9682
275 | 2010-05-16T16:38:25.051850Z
276 | 4
277 | daniel
278 |
279 |
280 |
281 |
282 |
283 |
284 |
285 |
286 |
287 |
288 |
289 |
290 |
291 |
292 |
293 |
294 |
295 |
296 |
297 |
298 |
299 | 7974
300 |
301 | NSObject+SBJSON.h
302 | file
303 |
304 |
305 |
306 |
307 | 2010-05-16T16:12:47.000000Z
308 | f7f559bceafad09d4253aaf5048d33e6
309 | 2010-05-16T16:38:25.051850Z
310 | 4
311 | daniel
312 |
313 |
314 |
315 |
316 |
317 |
318 |
319 |
320 |
321 |
322 |
323 |
324 |
325 |
326 |
327 |
328 |
329 |
330 |
331 |
332 |
333 | 2561
334 |
335 | NSString+SBJSON.h
336 | file
337 |
338 |
339 |
340 |
341 | 2010-05-16T16:12:47.000000Z
342 | b133112104c190709fbbd07da0ee7b2c
343 | 2010-05-16T16:38:25.051850Z
344 | 4
345 | daniel
346 |
347 |
348 |
349 |
350 |
351 |
352 |
353 |
354 |
355 |
356 |
357 |
358 |
359 |
360 |
361 |
362 |
363 |
364 |
365 |
366 |
367 | 2326
368 |
369 | SBJSON.m
370 | file
371 |
372 |
373 |
374 |
375 | 2010-05-16T16:12:47.000000Z
376 | 53d1eb806d6cc3dab7e82238b29c8f4e
377 | 2010-05-16T16:38:25.051850Z
378 | 4
379 | daniel
380 |
381 |
382 |
383 |
384 |
385 |
386 |
387 |
388 |
389 |
390 |
391 |
392 |
393 |
394 |
395 |
396 |
397 |
398 |
399 |
400 |
401 | 6844
402 |
403 | NSObject+SBJSON.m
404 | file
405 |
406 |
407 |
408 |
409 | 2010-05-16T16:12:47.000000Z
410 | c7db91f721f715e70b26e88a2a2da90e
411 | 2010-05-16T16:38:25.051850Z
412 | 4
413 | daniel
414 |
415 |
416 |
417 |
418 |
419 |
420 |
421 |
422 |
423 |
424 |
425 |
426 |
427 |
428 |
429 |
430 |
431 |
432 |
433 |
434 |
435 | 2206
436 |
437 | NSString+SBJSON.m
438 | file
439 |
440 |
441 |
442 |
443 | 2010-05-16T16:12:47.000000Z
444 | 8b741eab04ec172ec1d8629b923fc9a8
445 | 2010-05-16T16:38:25.051850Z
446 | 4
447 | daniel
448 |
449 |
450 |
451 |
452 |
453 |
454 |
455 |
456 |
457 |
458 |
459 |
460 |
461 |
462 |
463 |
464 |
465 |
466 |
467 |
468 |
469 | 2173
470 |
471 |
--------------------------------------------------------------------------------
/PSGoogleReader/SBJSON/.svn/text-base/JSON.h.svn-base:
--------------------------------------------------------------------------------
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 | /**
31 | @mainpage A strict JSON parser and generator for Objective-C
32 |
33 | JSON (JavaScript Object Notation) is a lightweight data-interchange
34 | format. This framework provides two apis for parsing and generating
35 | JSON. One standard object-based and a higher level api consisting of
36 | categories added to existing Objective-C classes.
37 |
38 | Learn more on the http://code.google.com/p/json-framework project site.
39 |
40 | This framework does its best to be as strict as possible, both in what it
41 | accepts and what it generates. For example, it does not support trailing commas
42 | in arrays or objects. Nor does it support embedded comments, or
43 | anything else not in the JSON specification. This is considered a feature.
44 |
45 | */
46 |
47 | #import "SBJSON.h"
48 | #import "NSObject+SBJSON.h"
49 | #import "NSString+SBJSON.h"
50 |
51 |
--------------------------------------------------------------------------------
/PSGoogleReader/SBJSON/.svn/text-base/NSObject+SBJSON.h.svn-base:
--------------------------------------------------------------------------------
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
31 |
32 |
33 | /**
34 | @brief Adds JSON generation to Foundation classes
35 |
36 | This is a category on NSObject that adds methods for returning JSON representations
37 | of standard objects to the objects themselves. This means you can call the
38 | -JSONRepresentation method on an NSArray object and it'll do what you want.
39 | */
40 | @interface NSObject (NSObject_SBJSON)
41 |
42 | /**
43 | @brief Returns a string containing the receiver encoded as a JSON fragment.
44 |
45 | This method is added as a category on NSObject but is only actually
46 | supported for the following objects:
47 | @li NSDictionary
48 | @li NSArray
49 | @li NSString
50 | @li NSNumber (also used for booleans)
51 | @li NSNull
52 |
53 | @deprecated Given we bill ourselves as a "strict" JSON library, this method should be removed.
54 | */
55 | - (NSString *)JSONFragment;
56 |
57 | /**
58 | @brief Returns a string containing the receiver encoded in JSON.
59 |
60 | This method is added as a category on NSObject but is only actually
61 | supported for the following objects:
62 | @li NSDictionary
63 | @li NSArray
64 | */
65 | - (NSString *)JSONRepresentation;
66 |
67 | @end
68 |
69 |
--------------------------------------------------------------------------------
/PSGoogleReader/SBJSON/.svn/text-base/NSObject+SBJSON.m.svn-base:
--------------------------------------------------------------------------------
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 "NSObject+SBJSON.h"
31 | #import "SBJsonWriter.h"
32 |
33 | @implementation NSObject (NSObject_SBJSON)
34 |
35 | - (NSString *)JSONFragment {
36 | SBJsonWriter *jsonWriter = [SBJsonWriter new];
37 | NSString *json = [jsonWriter stringWithFragment:self];
38 | if (!json)
39 | NSLog(@"-JSONFragment failed. Error trace is: %@", [jsonWriter errorTrace]);
40 | [jsonWriter release];
41 | return json;
42 | }
43 |
44 | - (NSString *)JSONRepresentation {
45 | SBJsonWriter *jsonWriter = [SBJsonWriter new];
46 | NSString *json = [jsonWriter stringWithObject:self];
47 | if (!json)
48 | NSLog(@"-JSONRepresentation failed. Error trace is: %@", [jsonWriter errorTrace]);
49 | [jsonWriter release];
50 | return json;
51 | }
52 |
53 | @end
54 |
--------------------------------------------------------------------------------
/PSGoogleReader/SBJSON/.svn/text-base/NSString+SBJSON.h.svn-base:
--------------------------------------------------------------------------------
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
31 |
32 | /**
33 | @brief Adds JSON parsing methods to NSString
34 |
35 | This is a category on NSString that adds methods for parsing the target string.
36 | */
37 | @interface NSString (NSString_SBJSON)
38 |
39 |
40 | /**
41 | @brief Returns the object represented in the receiver, or nil on error.
42 |
43 | Returns a a scalar object represented by the string's JSON fragment representation.
44 |
45 | @deprecated Given we bill ourselves as a "strict" JSON library, this method should be removed.
46 | */
47 | - (id)JSONFragmentValue;
48 |
49 | /**
50 | @brief Returns the NSDictionary or NSArray represented by the current string's JSON representation.
51 |
52 | Returns the dictionary or array represented in the receiver, or nil on error.
53 |
54 | Returns the NSDictionary or NSArray represented by the current string's JSON representation.
55 | */
56 | - (id)JSONValue;
57 |
58 | @end
59 |
--------------------------------------------------------------------------------
/PSGoogleReader/SBJSON/.svn/text-base/NSString+SBJSON.m.svn-base:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (C) 2007-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 "NSString+SBJSON.h"
31 | #import "SBJsonParser.h"
32 |
33 | @implementation NSString (NSString_SBJSON)
34 |
35 | - (id)JSONFragmentValue
36 | {
37 | SBJsonParser *jsonParser = [SBJsonParser new];
38 | id repr = [jsonParser fragmentWithString:self];
39 | if (!repr)
40 | NSLog(@"-JSONFragmentValue failed. Error trace is: %@", [jsonParser errorTrace]);
41 | [jsonParser release];
42 | return repr;
43 | }
44 |
45 | - (id)JSONValue
46 | {
47 | SBJsonParser *jsonParser = [SBJsonParser new];
48 | id repr = [jsonParser objectWithString:self];
49 | if (!repr)
50 | NSLog(@"-JSONValue failed. Error trace is: %@", [jsonParser errorTrace]);
51 | [jsonParser release];
52 | return repr;
53 | }
54 |
55 | @end
56 |
--------------------------------------------------------------------------------
/PSGoogleReader/SBJSON/.svn/text-base/SBJSON.h.svn-base:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (C) 2007-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
31 | #import "SBJsonParser.h"
32 | #import "SBJsonWriter.h"
33 |
34 | /**
35 | @brief Facade for SBJsonWriter/SBJsonParser.
36 |
37 | Requests are forwarded to instances of SBJsonWriter and SBJsonParser.
38 | */
39 | @interface SBJSON : SBJsonBase {
40 |
41 | @private
42 | SBJsonParser *jsonParser;
43 | SBJsonWriter *jsonWriter;
44 | }
45 |
46 |
47 | /// Return the fragment represented by the given string
48 | - (id)fragmentWithString:(NSString*)jsonrep
49 | error:(NSError**)error;
50 |
51 | /// Return the object represented by the given string
52 | - (id)objectWithString:(NSString*)jsonrep
53 | error:(NSError**)error;
54 |
55 | /// Parse the string and return the represented object (or scalar)
56 | - (id)objectWithString:(id)value
57 | allowScalar:(BOOL)x
58 | error:(NSError**)error;
59 |
60 |
61 | /// Return JSON representation of an array or dictionary
62 | - (NSString*)stringWithObject:(id)value
63 | error:(NSError**)error;
64 |
65 | /// Return JSON representation of any legal JSON value
66 | - (NSString*)stringWithFragment:(id)value
67 | error:(NSError**)error;
68 |
69 | /// Return JSON representation (or fragment) for the given object
70 | - (NSString*)stringWithObject:(id)value
71 | allowScalar:(BOOL)x
72 | error:(NSError**)error;
73 |
74 |
75 | @end
76 |
--------------------------------------------------------------------------------
/PSGoogleReader/SBJSON/.svn/text-base/SBJSON.m.svn-base:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (C) 2007-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 "SBJSON.h"
31 |
32 | @implementation SBJSON
33 |
34 | - (id)init {
35 | self = [super init];
36 | if (self) {
37 | jsonWriter = [SBJsonWriter new];
38 | jsonParser = [SBJsonParser new];
39 | [self setMaxDepth:512];
40 |
41 | }
42 | return self;
43 | }
44 |
45 | - (void)dealloc {
46 | [jsonWriter release];
47 | [jsonParser release];
48 | [super dealloc];
49 | }
50 |
51 | #pragma mark Writer
52 |
53 |
54 | - (NSString *)stringWithObject:(id)obj {
55 | NSString *repr = [jsonWriter stringWithObject:obj];
56 | if (repr)
57 | return repr;
58 |
59 | [errorTrace release];
60 | errorTrace = [[jsonWriter errorTrace] mutableCopy];
61 | return nil;
62 | }
63 |
64 | /**
65 | Returns a string containing JSON representation of the passed in value, or nil on error.
66 | If nil is returned and @p error is not NULL, @p *error can be interrogated to find the cause of the error.
67 |
68 | @param value any instance that can be represented as a JSON fragment
69 | @param allowScalar wether to return json fragments for scalar objects
70 | @param error used to return an error by reference (pass NULL if this is not desired)
71 |
72 | @deprecated Given we bill ourselves as a "strict" JSON library, this method should be removed.
73 | */
74 | - (NSString*)stringWithObject:(id)value allowScalar:(BOOL)allowScalar error:(NSError**)error {
75 |
76 | NSString *json = allowScalar ? [jsonWriter stringWithFragment:value] : [jsonWriter stringWithObject:value];
77 | if (json)
78 | return json;
79 |
80 | [errorTrace release];
81 | errorTrace = [[jsonWriter errorTrace] mutableCopy];
82 |
83 | if (error)
84 | *error = [errorTrace lastObject];
85 | return nil;
86 | }
87 |
88 | /**
89 | Returns a string containing JSON representation of the passed in value, or nil on error.
90 | If nil is returned and @p error is not NULL, @p error can be interrogated to find the cause of the error.
91 |
92 | @param value any instance that can be represented as a JSON fragment
93 | @param error used to return an error by reference (pass NULL if this is not desired)
94 |
95 | @deprecated Given we bill ourselves as a "strict" JSON library, this method should be removed.
96 | */
97 | - (NSString*)stringWithFragment:(id)value error:(NSError**)error {
98 | return [self stringWithObject:value
99 | allowScalar:YES
100 | error:error];
101 | }
102 |
103 | /**
104 | Returns a string containing JSON representation of the passed in value, or nil on error.
105 | If nil is returned and @p error is not NULL, @p error can be interrogated to find the cause of the error.
106 |
107 | @param value a NSDictionary or NSArray instance
108 | @param error used to return an error by reference (pass NULL if this is not desired)
109 | */
110 | - (NSString*)stringWithObject:(id)value error:(NSError**)error {
111 | return [self stringWithObject:value
112 | allowScalar:NO
113 | error:error];
114 | }
115 |
116 | #pragma mark Parsing
117 |
118 | - (id)objectWithString:(NSString *)repr {
119 | id obj = [jsonParser objectWithString:repr];
120 | if (obj)
121 | return obj;
122 |
123 | [errorTrace release];
124 | errorTrace = [[jsonParser errorTrace] mutableCopy];
125 |
126 | return nil;
127 | }
128 |
129 | /**
130 | Returns the object represented by the passed-in string or nil on error. The returned object can be
131 | a string, number, boolean, null, array or dictionary.
132 |
133 | @param value the json string to parse
134 | @param allowScalar whether to return objects for JSON fragments
135 | @param error used to return an error by reference (pass NULL if this is not desired)
136 |
137 | @deprecated Given we bill ourselves as a "strict" JSON library, this method should be removed.
138 | */
139 | - (id)objectWithString:(id)value allowScalar:(BOOL)allowScalar error:(NSError**)error {
140 |
141 | id obj = allowScalar ? [jsonParser fragmentWithString:value] : [jsonParser objectWithString:value];
142 | if (obj)
143 | return obj;
144 |
145 | [errorTrace release];
146 | errorTrace = [[jsonParser errorTrace] mutableCopy];
147 |
148 | if (error)
149 | *error = [errorTrace lastObject];
150 | return nil;
151 | }
152 |
153 | /**
154 | Returns the object represented by the passed-in string or nil on error. The returned object can be
155 | a string, number, boolean, null, array or dictionary.
156 |
157 | @param repr the json string to parse
158 | @param error used to return an error by reference (pass NULL if this is not desired)
159 |
160 | @deprecated Given we bill ourselves as a "strict" JSON library, this method should be removed.
161 | */
162 | - (id)fragmentWithString:(NSString*)repr error:(NSError**)error {
163 | return [self objectWithString:repr
164 | allowScalar:YES
165 | error:error];
166 | }
167 |
168 | /**
169 | Returns the object represented by the passed-in string or nil on error. The returned object
170 | will be either a dictionary or an array.
171 |
172 | @param repr the json string to parse
173 | @param error used to return an error by reference (pass NULL if this is not desired)
174 | */
175 | - (id)objectWithString:(NSString*)repr error:(NSError**)error {
176 | return [self objectWithString:repr
177 | allowScalar:NO
178 | error:error];
179 | }
180 |
181 |
182 |
183 | #pragma mark Properties - parsing
184 |
185 | - (NSUInteger)maxDepth {
186 | return jsonParser.maxDepth;
187 | }
188 |
189 | - (void)setMaxDepth:(NSUInteger)d {
190 | jsonWriter.maxDepth = jsonParser.maxDepth = d;
191 | }
192 |
193 |
194 | #pragma mark Properties - writing
195 |
196 | - (BOOL)humanReadable {
197 | return jsonWriter.humanReadable;
198 | }
199 |
200 | - (void)setHumanReadable:(BOOL)x {
201 | jsonWriter.humanReadable = x;
202 | }
203 |
204 | - (BOOL)sortKeys {
205 | return jsonWriter.sortKeys;
206 | }
207 |
208 | - (void)setSortKeys:(BOOL)x {
209 | jsonWriter.sortKeys = x;
210 | }
211 |
212 | @end
213 |
--------------------------------------------------------------------------------
/PSGoogleReader/SBJSON/.svn/text-base/SBJsonBase.h.svn-base:
--------------------------------------------------------------------------------
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
31 |
32 | extern NSString * SBJSONErrorDomain;
33 |
34 |
35 | enum {
36 | EUNSUPPORTED = 1,
37 | EPARSENUM,
38 | EPARSE,
39 | EFRAGMENT,
40 | ECTRL,
41 | EUNICODE,
42 | EDEPTH,
43 | EESCAPE,
44 | ETRAILCOMMA,
45 | ETRAILGARBAGE,
46 | EEOF,
47 | EINPUT
48 | };
49 |
50 | /**
51 | @brief Common base class for parsing & writing.
52 |
53 | This class contains the common error-handling code and option between the parser/writer.
54 | */
55 | @interface SBJsonBase : NSObject {
56 | NSMutableArray *errorTrace;
57 |
58 | @protected
59 | NSUInteger depth, maxDepth;
60 | }
61 |
62 | /**
63 | @brief The maximum recursing depth.
64 |
65 | Defaults to 512. If the input is nested deeper than this the input will be deemed to be
66 | malicious and the parser returns nil, signalling an error. ("Nested too deep".) You can
67 | turn off this security feature by setting the maxDepth value to 0.
68 | */
69 | @property NSUInteger maxDepth;
70 |
71 | /**
72 | @brief Return an error trace, or nil if there was no errors.
73 |
74 | Note that this method returns the trace of the last method that failed.
75 | You need to check the return value of the call you're making to figure out
76 | if the call actually failed, before you know call this method.
77 | */
78 | @property(copy,readonly) NSArray* errorTrace;
79 |
80 | /// @internal for use in subclasses to add errors to the stack trace
81 | - (void)addErrorWithCode:(NSUInteger)code description:(NSString*)str;
82 |
83 | /// @internal for use in subclasess to clear the error before a new parsing attempt
84 | - (void)clearErrorTrace;
85 |
86 | @end
87 |
--------------------------------------------------------------------------------
/PSGoogleReader/SBJSON/.svn/text-base/SBJsonBase.m.svn-base:
--------------------------------------------------------------------------------
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 "SBJsonBase.h"
31 | NSString * SBJSONErrorDomain = @"org.brautaset.JSON.ErrorDomain";
32 |
33 |
34 | @implementation SBJsonBase
35 |
36 | @synthesize errorTrace;
37 | @synthesize maxDepth;
38 |
39 | - (id)init {
40 | self = [super init];
41 | if (self)
42 | self.maxDepth = 512;
43 | return self;
44 | }
45 |
46 | - (void)dealloc {
47 | [errorTrace release];
48 | [super dealloc];
49 | }
50 |
51 | - (void)addErrorWithCode:(NSUInteger)code description:(NSString*)str {
52 | NSDictionary *userInfo;
53 | if (!errorTrace) {
54 | errorTrace = [NSMutableArray new];
55 | userInfo = [NSDictionary dictionaryWithObject:str forKey:NSLocalizedDescriptionKey];
56 |
57 | } else {
58 | userInfo = [NSDictionary dictionaryWithObjectsAndKeys:
59 | str, NSLocalizedDescriptionKey,
60 | [errorTrace lastObject], NSUnderlyingErrorKey,
61 | nil];
62 | }
63 |
64 | NSError *error = [NSError errorWithDomain:SBJSONErrorDomain code:code userInfo:userInfo];
65 |
66 | [self willChangeValueForKey:@"errorTrace"];
67 | [errorTrace addObject:error];
68 | [self didChangeValueForKey:@"errorTrace"];
69 | }
70 |
71 | - (void)clearErrorTrace {
72 | [self willChangeValueForKey:@"errorTrace"];
73 | [errorTrace release];
74 | errorTrace = nil;
75 | [self didChangeValueForKey:@"errorTrace"];
76 | }
77 |
78 | @end
79 |
--------------------------------------------------------------------------------
/PSGoogleReader/SBJSON/.svn/text-base/SBJsonParser.h.svn-base:
--------------------------------------------------------------------------------
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
31 | #import "SBJsonBase.h"
32 |
33 | /**
34 | @brief Options for the parser class.
35 |
36 | This exists so the SBJSON facade can implement the options in the parser without having to re-declare them.
37 | */
38 | @protocol SBJsonParser
39 |
40 | /**
41 | @brief Return the object represented by the given string.
42 |
43 | Returns the object represented by the passed-in string or nil on error. The returned object can be
44 | a string, number, boolean, null, array or dictionary.
45 |
46 | @param repr the json string to parse
47 | */
48 | - (id)objectWithString:(NSString *)repr;
49 |
50 | @end
51 |
52 |
53 | /**
54 | @brief The JSON parser class.
55 |
56 | JSON is mapped to Objective-C types in the following way:
57 |
58 | @li Null -> NSNull
59 | @li String -> NSMutableString
60 | @li Array -> NSMutableArray
61 | @li Object -> NSMutableDictionary
62 | @li Boolean -> NSNumber (initialised with -initWithBool:)
63 | @li Number -> NSDecimalNumber
64 |
65 | Since Objective-C doesn't have a dedicated class for boolean values, these turns into NSNumber
66 | instances. These are initialised with the -initWithBool: method, and
67 | round-trip back to JSON properly. (They won't silently suddenly become 0 or 1; they'll be
68 | represented as 'true' and 'false' again.)
69 |
70 | JSON numbers turn into NSDecimalNumber instances,
71 | as we can thus avoid any loss of precision. (JSON allows ridiculously large numbers.)
72 |
73 | */
74 | @interface SBJsonParser : SBJsonBase {
75 |
76 | @private
77 | const char *c;
78 | }
79 |
80 | @end
81 |
82 | // don't use - exists for backwards compatibility with 2.1.x only. Will be removed in 2.3.
83 | @interface SBJsonParser (Private)
84 | - (id)fragmentWithString:(id)repr;
85 | @end
86 |
87 |
88 |
--------------------------------------------------------------------------------
/PSGoogleReader/SBJSON/.svn/text-base/SBJsonWriter.h.svn-base:
--------------------------------------------------------------------------------
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
31 | #import "SBJsonBase.h"
32 |
33 | /**
34 | @brief Options for the writer class.
35 |
36 | This exists so the SBJSON facade can implement the options in the writer without having to re-declare them.
37 | */
38 | @protocol SBJsonWriter
39 |
40 | /**
41 | @brief Whether we are generating human-readable (multiline) JSON.
42 |
43 | Set whether or not to generate human-readable JSON. The default is NO, which produces
44 | JSON without any whitespace. (Except inside strings.) If set to YES, generates human-readable
45 | JSON with linebreaks after each array value and dictionary key/value pair, indented two
46 | spaces per nesting level.
47 | */
48 | @property BOOL humanReadable;
49 |
50 | /**
51 | @brief Whether or not to sort the dictionary keys in the output.
52 |
53 | If this is set to YES, the dictionary keys in the JSON output will be in sorted order.
54 | (This is useful if you need to compare two structures, for example.) The default is NO.
55 | */
56 | @property BOOL sortKeys;
57 |
58 | /**
59 | @brief Return JSON representation (or fragment) for the given object.
60 |
61 | Returns a string containing JSON representation of the passed in value, or nil on error.
62 | If nil is returned and @p error is not NULL, @p *error can be interrogated to find the cause of the error.
63 |
64 | @param value any instance that can be represented as a JSON fragment
65 |
66 | */
67 | - (NSString*)stringWithObject:(id)value;
68 |
69 | @end
70 |
71 |
72 | /**
73 | @brief The JSON writer class.
74 |
75 | Objective-C types are mapped to JSON types in the following way:
76 |
77 | @li NSNull -> Null
78 | @li NSString -> String
79 | @li NSArray -> Array
80 | @li NSDictionary -> Object
81 | @li NSNumber (-initWithBool:) -> Boolean
82 | @li NSNumber -> Number
83 |
84 | In JSON the keys of an object must be strings. NSDictionary keys need
85 | not be, but attempting to convert an NSDictionary with non-string keys
86 | into JSON will throw an exception.
87 |
88 | NSNumber instances created with the +initWithBool: method are
89 | converted into the JSON boolean "true" and "false" values, and vice
90 | versa. Any other NSNumber instances are converted to a JSON number the
91 | way you would expect.
92 |
93 | */
94 | @interface SBJsonWriter : SBJsonBase {
95 |
96 | @private
97 | BOOL sortKeys, humanReadable;
98 | }
99 |
100 | @end
101 |
102 | // don't use - exists for backwards compatibility. Will be removed in 2.3.
103 | @interface SBJsonWriter (Private)
104 | - (NSString*)stringWithFragment:(id)value;
105 | @end
106 |
107 | /**
108 | @brief Allows generation of JSON for otherwise unsupported classes.
109 |
110 | If you have a custom class that you want to create a JSON representation for you can implement
111 | this method in your class. It should return a representation of your object defined
112 | in terms of objects that can be translated into JSON. For example, a Person
113 | object might implement it like this:
114 |
115 | @code
116 | - (id)jsonProxyObject {
117 | return [NSDictionary dictionaryWithObjectsAndKeys:
118 | name, @"name",
119 | phone, @"phone",
120 | email, @"email",
121 | nil];
122 | }
123 | @endcode
124 |
125 | */
126 | @interface NSObject (SBProxyForJson)
127 | - (id)proxyForJson;
128 | @end
129 |
130 |
--------------------------------------------------------------------------------
/PSGoogleReader/SBJSON/.svn/text-base/SBJsonWriter.m.svn-base:
--------------------------------------------------------------------------------
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
238 |
--------------------------------------------------------------------------------
/PSGoogleReader/SBJSON/NSObject+SBJson.h:
--------------------------------------------------------------------------------
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
31 |
32 | #pragma mark JSON Writing
33 |
34 | /// Adds JSON generation to NSObject
35 | @interface NSObject (NSObject_SBJsonWriting)
36 |
37 | /**
38 | @brief Encodes the receiver into a JSON string
39 |
40 | Although defined as a category on NSObject it is only defined for NSArray and NSDictionary.
41 |
42 | @return the receiver encoded in JSON, or nil on error.
43 |
44 | @see @ref objc2json
45 | */
46 | - (NSString *)JSONRepresentation;
47 |
48 | @end
49 |
50 |
51 | #pragma mark JSON Parsing
52 |
53 | /// Adds JSON parsing methods to NSString
54 | @interface NSString (NSString_SBJsonParsing)
55 |
56 | /**
57 | @brief Decodes the receiver's JSON text
58 |
59 | @return the NSDictionary or NSArray represented by the receiver, or nil on error.
60 |
61 | @see @ref json2objc
62 | */
63 | - (id)JSONValue;
64 |
65 | @end
66 |
67 |
68 |
--------------------------------------------------------------------------------
/PSGoogleReader/SBJSON/NSObject+SBJson.m:
--------------------------------------------------------------------------------
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 "NSObject+SBJson.h"
31 | #import "SBJsonWriter.h"
32 | #import "SBJsonParser.h"
33 |
34 | @implementation NSObject (NSObject_SBJsonWriting)
35 |
36 | - (NSString *)JSONRepresentation {
37 | SBJsonWriter *writer = [[SBJsonWriter alloc] init];
38 | NSString *json = [writer stringWithObject:self];
39 | if (!json)
40 | NSLog(@"-JSONRepresentation failed. Error is: %@", writer.error);
41 | return json;
42 | }
43 |
44 | @end
45 |
46 |
47 |
48 | @implementation NSString (NSString_SBJsonParsing)
49 |
50 | - (id)JSONValue {
51 | SBJsonParser *parser = [[SBJsonParser alloc] init];
52 | id repr = [parser objectWithString:self];
53 | if (!repr)
54 | NSLog(@"-JSONValue failed. Error is: %@", parser.error);
55 | return repr;
56 | }
57 |
58 | @end
59 |
--------------------------------------------------------------------------------
/PSGoogleReader/SBJSON/SBJson.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (C) 2009-2011 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 | /**
31 | @page json2objc JSON to Objective-C
32 |
33 | JSON is mapped to Objective-C types in the following way:
34 |
35 | @li null -> NSNull
36 | @li string -> NSString
37 | @li array -> NSMutableArray
38 | @li object -> NSMutableDictionary
39 | @li true -> NSNumber's -numberWithBool:YES
40 | @li false -> NSNumber's -numberWithBool:NO
41 | @li integer up to 19 digits -> NSNumber's -numberWithLongLong:
42 | @li all other numbers -> NSDecimalNumber
43 |
44 | Since Objective-C doesn't have a dedicated class for boolean values,
45 | these turns into NSNumber instances. However, since these are
46 | initialised with the -initWithBool: method they round-trip back to JSON
47 | properly. In other words, they won't silently suddenly become 0 or 1;
48 | they'll be represented as 'true' and 'false' again.
49 |
50 | As an optimisation integers up to 19 digits in length (the max length
51 | for signed long long integers) turn into NSNumber instances, while
52 | complex ones turn into NSDecimalNumber instances. We can thus avoid any
53 | loss of precision as JSON allows ridiculously large numbers.
54 |
55 | @page objc2json Objective-C to JSON
56 |
57 | Objective-C types are mapped to JSON types in the following way:
58 |
59 | @li NSNull -> null
60 | @li NSString -> string
61 | @li NSArray -> array
62 | @li NSDictionary -> object
63 | @li NSNumber's -initWithBool:YES -> true
64 | @li NSNumber's -initWithBool:NO -> false
65 | @li NSNumber -> number
66 |
67 | @note In JSON the keys of an object must be strings. NSDictionary
68 | keys need not be, but attempting to convert an NSDictionary with
69 | non-string keys into JSON will throw an exception.
70 |
71 | NSNumber instances created with the -numberWithBool: method are
72 | converted into the JSON boolean "true" and "false" values, and vice
73 | versa. Any other NSNumber instances are converted to a JSON number the
74 | way you would expect.
75 |
76 | */
77 |
78 | #import "SBJsonParser.h"
79 | #import "SBJsonWriter.h"
80 | #import "SBJsonStreamParser.h"
81 | #import "SBJsonStreamWriter.h"
82 | #import "NSObject+SBJson.h"
83 |
84 |
--------------------------------------------------------------------------------
/PSGoogleReader/SBJSON/SBJsonParser.h:
--------------------------------------------------------------------------------
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
31 |
32 | /**
33 | @brief Parse JSON Strings and NSData objects
34 |
35 | This uses SBJsonStreamParser internally.
36 |
37 | @see @ref objc2json
38 |
39 | */
40 |
41 | @interface SBJsonParser : NSObject
42 |
43 | /**
44 | @brief The maximum recursing depth.
45 |
46 | Defaults to 32. If the input is nested deeper than this the input will be deemed to be
47 | malicious and the parser returns nil, signalling an error. ("Nested too deep".) You can
48 | turn off this security feature by setting the maxDepth value to 0.
49 | */
50 | @property NSUInteger maxDepth;
51 |
52 | /**
53 | @brief Description of parse error
54 |
55 | This method returns the trace of the last method that failed.
56 | You need to check the return value of the call you're making to figure out
57 | if the call actually failed, before you know call this method.
58 |
59 | @return A string describing the error encountered, or nil if no error occured.
60 |
61 | */
62 | @property(copy) NSString *error;
63 |
64 | /**
65 | @brief Return the object represented by the given NSData object.
66 |
67 | The data *must* be UTF8 encoded.
68 |
69 | @param data An NSData containing UTF8 encoded data to parse.
70 | @return The NSArray or NSDictionary represented by the object, or nil if an error occured.
71 |
72 | */
73 | - (id)objectWithData:(NSData*)data;
74 |
75 | /**
76 | @brief Return the object represented by the given string
77 |
78 | This method converts its input to an NSData object containing UTF8 and calls -objectWithData: with it.
79 |
80 | @return The NSArray or NSDictionary represented by the object, or nil if an error occured.
81 | */
82 | - (id)objectWithString:(NSString *)repr;
83 |
84 | /**
85 | @brief Return the object represented by the given string
86 |
87 | This method calls objectWithString: internally. If an error occurs, and if @p error
88 | is not nil, it creates an NSError object and returns this through its second argument.
89 |
90 | @param jsonText the json string to parse
91 | @param error pointer to an NSError object to populate on error
92 |
93 | @return The NSArray or NSDictionary represented by the object, or nil if an error occured.
94 | */
95 |
96 | - (id)objectWithString:(NSString*)jsonText
97 | error:(NSError**)error;
98 |
99 | @end
100 |
101 |
102 |
--------------------------------------------------------------------------------
/PSGoogleReader/SBJSON/SBJsonParser.m:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (C) 2009,2010 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 "SBJsonParser.h"
31 | #import "SBJsonStreamParser.h"
32 | #import "SBJsonStreamParserAccumulator.h"
33 |
34 | @implementation SBJsonParser
35 |
36 | @synthesize maxDepth;
37 | @synthesize error;
38 |
39 | - (id)init {
40 | self = [super init];
41 | if (self)
42 | self.maxDepth = 32u;
43 | return self;
44 | }
45 |
46 |
47 | #pragma mark Methods
48 |
49 | - (id)objectWithData:(NSData *)data {
50 |
51 | if (!data) {
52 | self.error = @"Input was 'nil'";
53 | return nil;
54 | }
55 |
56 | SBJsonStreamParserAccumulator *accumulator = [[SBJsonStreamParserAccumulator alloc] init];
57 |
58 | SBJsonStreamParser *parser = [[SBJsonStreamParser alloc] init];
59 | parser.maxDepth = self.maxDepth;
60 | parser.delegate = accumulator;
61 |
62 | switch ([parser parse:data]) {
63 | case SBJsonStreamParserComplete:
64 | return accumulator.value;
65 | break;
66 |
67 | case SBJsonStreamParserWaitingForData:
68 | self.error = @"Unexpected end of input";
69 | break;
70 |
71 | case SBJsonStreamParserError:
72 | self.error = parser.error;
73 | break;
74 | }
75 |
76 | return nil;
77 | }
78 |
79 | - (id)objectWithString:(NSString *)repr {
80 | return [self objectWithData:[repr dataUsingEncoding:NSUTF8StringEncoding]];
81 | }
82 |
83 | - (id)objectWithString:(NSString*)repr error:(NSError**)error_ {
84 | id tmp = [self objectWithString:repr];
85 | if (tmp)
86 | return tmp;
87 |
88 | if (error_) {
89 | NSDictionary *ui = [NSDictionary dictionaryWithObjectsAndKeys:error, NSLocalizedDescriptionKey, nil];
90 | *error_ = [NSError errorWithDomain:@"org.brautaset.SBJsonParser.ErrorDomain" code:0 userInfo:ui];
91 | }
92 |
93 | return nil;
94 | }
95 |
96 | @end
97 |
--------------------------------------------------------------------------------
/PSGoogleReader/SBJSON/SBJsonStreamParser.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2010, Stig Brautaset.
3 | All rights reserved.
4 |
5 | Redistribution and use in source and binary forms, with or without
6 | modification, are permitted provided that the following conditions are
7 | met:
8 |
9 | Redistributions of source code must retain the above copyright
10 | notice, this list of conditions and the following disclaimer.
11 |
12 | Redistributions in binary form must reproduce the above copyright
13 | notice, this list of conditions and the following disclaimer in the
14 | documentation and/or other materials provided with the distribution.
15 |
16 | Neither the name of the the author nor the names of its contributors
17 | may be used to endorse or promote products derived from this software
18 | without specific prior written permission.
19 |
20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
21 | IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
23 | PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 | HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 | */
32 |
33 | #import
34 |
35 | @class SBJsonTokeniser;
36 | @class SBJsonStreamParser;
37 | @class SBJsonStreamParserState;
38 |
39 | typedef enum {
40 | SBJsonStreamParserComplete,
41 | SBJsonStreamParserWaitingForData,
42 | SBJsonStreamParserError,
43 | } SBJsonStreamParserStatus;
44 |
45 |
46 | /**
47 | @brief SBJsonStreamParserDelegate protocol adapter
48 |
49 | @see SBJsonStreamParser
50 | */
51 | @protocol SBJsonStreamParserDelegate
52 |
53 | /**
54 | @brief Called if a JSON array is found
55 |
56 | This method is called if a JSON array is found.
57 |
58 | */
59 | - (void)parser:(SBJsonStreamParser*)parser foundArray:(NSArray*)array;
60 |
61 | /**
62 | @brief Called when a JSON object is found
63 |
64 | This method is called if a JSON object is found.
65 | */
66 | - (void)parser:(SBJsonStreamParser*)parser foundObject:(NSDictionary*)dict;
67 |
68 | @end
69 |
70 | typedef enum {
71 | SBJsonStreamParserNone,
72 | SBJsonStreamParserArray,
73 | SBJsonStreamParserObject,
74 | } SBJsonStreamParserType;
75 |
76 | /**
77 | @brief Parse a stream of JSON data.
78 |
79 | Using this class directly you can reduce the apparent latency for each
80 | download/parse cycle of documents over a slow connection. You can start
81 | parsing *and return chunks of the parsed document* before the entire
82 | document is downloaded. Using this class is also useful to parse huge
83 | documents on disk bit by bit so you don't have to keep them all in memory.
84 |
85 | The default behaviour is that the delegate only receives one call from
86 | either the -parser:foundArray: or -parser:foundObject: method when the
87 | document is fully parsed. However, if your inputs contains multiple JSON
88 | documents and you set the parser's -supportMultipleDocuments property to YES
89 | you will get one call for each full method.
90 |
91 | @code
92 | SBJsonStreamParser *parser = [[SBJsonStreamParser alloc] init];
93 | parser.delegate = self;
94 | parser.supportMultipleDocuments = YES;
95 |
96 | // Note that this input contains multiple top-level JSON documents
97 | NSData *json = [@"[]{}[]{}" dataWithEncoding:NSUTF8StringEncoding];
98 | [parser parse:data];
99 | @endcode
100 |
101 | In the above example @p self will have the following sequence of methods called on it:
102 |
103 | @li -parser:foundArray:
104 | @li -parser:foundObject:
105 | @li -parser:foundArray:
106 | @li -parser:foundObject:
107 |
108 | Often you won't have control over the input you're parsing, so can't make use of
109 | this feature. But, all is not lost: this class will let you get the same effect by
110 | allowing you to skip one or more of the outer enclosing objects. Thus, the next
111 | example results in the same sequence of -parser:foundArray: / -parser:foundObject:
112 | being called on your delegate.
113 |
114 | @code
115 | SBJsonStreamParser *parser = [[SBJsonStreamParser alloc] init];
116 | parser.delegate = self;
117 | parser.levelsToSkip = 1;
118 |
119 | // Note that this input contains A SINGLE top-level document
120 | NSData *json = [@"[[],{},[],{}]" dataWithEncoding:NSUTF8StringEncoding];
121 | [parser parse:data];
122 | @endcode
123 |
124 | @see SBJsonStreamParserDelegate
125 | @see @ref objc2json
126 |
127 | */
128 | @interface SBJsonStreamParser : NSObject {
129 | @private
130 | SBJsonTokeniser *tokeniser;
131 |
132 | NSUInteger depth;
133 | NSMutableArray *array;
134 | NSMutableDictionary *dict;
135 | NSMutableArray *keyStack;
136 | NSMutableArray *stack;
137 |
138 | SBJsonStreamParserType currentType;
139 | }
140 |
141 | @property (nonatomic, unsafe_unretained) SBJsonStreamParserState *state; // Private
142 | @property (nonatomic, readonly, strong) NSMutableArray *stateStack; // Private
143 |
144 |
145 | /**
146 | @brief How many levels to skip
147 |
148 | This is useful for parsing huge JSON documents, or documents coming in over a very slow link.
149 |
150 | If you set this to N it will skip the outer N levels and call the -parser:foundArray:
151 | or -parser:foundObject: methods for each of the inner objects, as appropriate.
152 |
153 | @see The StreamParserIntegrationTest.m file for examples
154 | */
155 | @property NSUInteger levelsToSkip;
156 |
157 | /**
158 | @brief Expect multiple documents separated by whitespace
159 |
160 | Normally the @p -parse: method returns SBJsonStreamParserComplete when it's found a complete JSON document.
161 | Attempting to parse any more data at that point is considered an error. ("Garbage after JSON".)
162 |
163 | If you set this property to true the parser will never return SBJsonStreamParserComplete. Rather,
164 | once an object is completed it will expect another object to immediately follow, separated
165 | only by (optional) whitespace.
166 |
167 | @see The TweetStream app in the Examples
168 | */
169 | @property BOOL supportMultipleDocuments;
170 |
171 | /**
172 | @brief Delegate to receive messages
173 |
174 | The object set here receives a series of messages as the parser breaks down the JSON stream
175 | into valid tokens.
176 |
177 | @note
178 | Usually this should be an instance of SBJsonStreamParser, but you can
179 | substitute your own implementation of the SBJsonStreamParserDelegate protocol if you need to.
180 | */
181 | @property (unsafe_unretained) id delegate;
182 |
183 | /**
184 | @brief The max parse depth
185 |
186 | If the input is nested deeper than this the parser will halt parsing and return an error.
187 |
188 | Defaults to 32.
189 | */
190 | @property NSUInteger maxDepth;
191 |
192 | /// Holds the error after SBJsonStreamParserError was returned
193 | @property (copy) NSString *error;
194 |
195 | /**
196 | @brief Parse some JSON
197 |
198 | The JSON is assumed to be UTF8 encoded. This can be a full JSON document, or a part of one.
199 |
200 | @param data An NSData object containing the next chunk of JSON
201 |
202 | @return
203 | @li SBJsonStreamParserComplete if a full document was found
204 | @li SBJsonStreamParserWaitingForData if a partial document was found and more data is required to complete it
205 | @li SBJsonStreamParserError if an error occured. (See the error property for details in this case.)
206 |
207 | */
208 | - (SBJsonStreamParserStatus)parse:(NSData*)data;
209 |
210 | @end
211 |
--------------------------------------------------------------------------------
/PSGoogleReader/SBJSON/SBJsonStreamParser.m:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2010, Stig Brautaset.
3 | All rights reserved.
4 |
5 | Redistribution and use in source and binary forms, with or without
6 | modification, are permitted provided that the following conditions are
7 | met:
8 |
9 | Redistributions of source code must retain the above copyright
10 | notice, this list of conditions and the following disclaimer.
11 |
12 | Redistributions in binary form must reproduce the above copyright
13 | notice, this list of conditions and the following disclaimer in the
14 | documentation and/or other materials provided with the distribution.
15 |
16 | Neither the name of the the author nor the names of its contributors
17 | may be used to endorse or promote products derived from this software
18 | without specific prior written permission.
19 |
20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
21 | IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
23 | PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 | HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 | */
32 |
33 | #import "SBJsonStreamParser.h"
34 | #import "SBJsonTokeniser.h"
35 | #import "SBJsonStreamParserState.h"
36 | #import
37 |
38 | static NSNumber *kTrue;
39 | static NSNumber *kFalse;
40 | static NSNull *kNull;
41 |
42 | @interface SBJsonStreamParser ()
43 |
44 | - (void)pop;
45 | - (void)parserFoundObject:(id)obj;
46 |
47 | @end
48 |
49 | @implementation SBJsonStreamParser
50 |
51 | @synthesize levelsToSkip;
52 | @synthesize supportMultipleDocuments;
53 | @synthesize error;
54 | @synthesize delegate;
55 | @synthesize maxDepth;
56 | @synthesize state;
57 | @synthesize stateStack;
58 |
59 | #pragma mark Housekeeping
60 |
61 | + (void)initialize {
62 | kTrue = [[NSNumber alloc] initWithBool:YES];
63 | kFalse = [[NSNumber alloc] initWithBool:NO];
64 | kNull = [NSNull null];
65 | }
66 |
67 | - (id)init {
68 | self = [super init];
69 | if (self) {
70 | maxDepth = 32u;
71 | stateStack = [[NSMutableArray alloc] initWithCapacity:maxDepth];
72 | state = [SBJsonStreamParserStateStart sharedInstance];
73 | tokeniser = [[SBJsonTokeniser alloc] init];
74 |
75 | keyStack = [[NSMutableArray alloc] initWithCapacity:32];
76 | stack = [[NSMutableArray alloc] initWithCapacity:32];
77 | currentType = SBJsonStreamParserNone;
78 |
79 | }
80 | return self;
81 | }
82 |
83 |
84 | #pragma mark Methods
85 |
86 | - (NSString*)tokenName:(sbjson_token_t)token {
87 | switch (token) {
88 | case sbjson_token_array_start:
89 | return @"start of array";
90 | break;
91 |
92 | case sbjson_token_array_end:
93 | return @"end of array";
94 | break;
95 |
96 | case sbjson_token_number:
97 | return @"number";
98 | break;
99 |
100 | case sbjson_token_string:
101 | return @"string";
102 | break;
103 |
104 | case sbjson_token_true:
105 | case sbjson_token_false:
106 | return @"boolean";
107 | break;
108 |
109 | case sbjson_token_null:
110 | return @"null";
111 | break;
112 |
113 | case sbjson_token_keyval_separator:
114 | return @"key-value separator";
115 | break;
116 |
117 | case sbjson_token_separator:
118 | return @"value separator";
119 | break;
120 |
121 | case sbjson_token_object_start:
122 | return @"start of object";
123 | break;
124 |
125 | case sbjson_token_object_end:
126 | return @"end of object";
127 | break;
128 |
129 | case sbjson_token_eof:
130 | case sbjson_token_error:
131 | break;
132 | }
133 | NSAssert(NO, @"Should not get here");
134 | return @"";
135 | }
136 |
137 | - (void)maxDepthError {
138 | self.error = [NSString stringWithFormat:@"Input depth exceeds max depth of %lu", maxDepth];
139 | self.state = [SBJsonStreamParserStateError sharedInstance];
140 | }
141 |
142 |
143 | - (void)pop {
144 | [stack removeLastObject];
145 | array = nil;
146 | dict = nil;
147 | currentType = SBJsonStreamParserNone;
148 |
149 | id value = [stack lastObject];
150 |
151 | if ([value isKindOfClass:[NSArray class]]) {
152 | array = value;
153 | currentType = SBJsonStreamParserArray;
154 | } else if ([value isKindOfClass:[NSDictionary class]]) {
155 | dict = value;
156 | currentType = SBJsonStreamParserObject;
157 | }
158 | }
159 |
160 | - (void)parserFoundObject:(id)obj {
161 | NSParameterAssert(obj);
162 |
163 | switch (currentType) {
164 | case SBJsonStreamParserArray:
165 | [array addObject:obj];
166 | break;
167 |
168 | case SBJsonStreamParserObject:
169 | NSParameterAssert(keyStack.count);
170 | [dict setObject:obj forKey:[keyStack lastObject]];
171 | [keyStack removeLastObject];
172 | break;
173 |
174 | case SBJsonStreamParserNone:
175 | if ([obj isKindOfClass:[NSArray class]]) {
176 | [delegate parser:self foundArray:obj];
177 | } else {
178 | [delegate parser:self foundObject:obj];
179 | }
180 | break;
181 |
182 | default:
183 | break;
184 | }
185 | }
186 |
187 | - (void)handleObjectStart {
188 | if (depth >= maxDepth) {
189 | [self maxDepthError];
190 | return;
191 | }
192 |
193 | [stateStack addObject:state];
194 | self.state = [SBJsonStreamParserStateObjectStart sharedInstance];
195 |
196 | if (++depth > levelsToSkip) {
197 | dict = [[NSMutableDictionary alloc] init];
198 | [stack addObject:dict];
199 |
200 | currentType = SBJsonStreamParserObject;
201 | }
202 | }
203 |
204 | - (void)handleObjectEnd: (sbjson_token_t) tok {
205 | self.state = [stateStack lastObject];
206 | [stateStack removeLastObject];
207 | [state parser:self shouldTransitionTo:tok];
208 |
209 | if (depth-- > levelsToSkip) {
210 | id value = dict;
211 | [self pop];
212 | [self parserFoundObject:value];
213 | }
214 | }
215 |
216 | - (void)handleArrayStart {
217 |
218 | if (depth >= maxDepth) {
219 | [self maxDepthError];
220 | return;
221 | }
222 |
223 | [stateStack addObject:state];
224 | self.state = [SBJsonStreamParserStateArrayStart sharedInstance];
225 |
226 | if (++depth > levelsToSkip) {
227 | array = [[NSMutableArray alloc] init];
228 | [stack addObject:array];
229 |
230 | currentType = SBJsonStreamParserArray;
231 | }
232 | }
233 |
234 | - (void)handleArrayEnd: (sbjson_token_t) tok {
235 | self.state = [stateStack lastObject];
236 | [stateStack removeLastObject];
237 | [state parser:self shouldTransitionTo:tok];
238 |
239 | if (depth-- > levelsToSkip) {
240 | id value = array;
241 | [self pop];
242 | [self parserFoundObject:value];
243 | }
244 | }
245 |
246 | - (void) handleTokenNotExpectedHere: (sbjson_token_t) tok {
247 | NSString *tokenName = [self tokenName:tok];
248 | NSString *stateName = [state name];
249 |
250 | self.error = [NSString stringWithFormat:@"Token '%@' not expected %@", tokenName, stateName];
251 | self.state = [SBJsonStreamParserStateError sharedInstance];
252 | }
253 |
254 | - (SBJsonStreamParserStatus)parse:(NSData *)data_ {
255 | [tokeniser appendData:data_];
256 |
257 | for (;;) {
258 |
259 | if ([state isError])
260 | return SBJsonStreamParserError;
261 |
262 | NSObject *token;
263 | sbjson_token_t tok = [tokeniser getToken:&token];
264 | switch (tok) {
265 | case sbjson_token_eof:
266 | return [state parserShouldReturn:self];
267 | break;
268 |
269 | case sbjson_token_error:
270 | self.state = [SBJsonStreamParserStateError sharedInstance];
271 | self.error = tokeniser.error;
272 | return SBJsonStreamParserError;
273 | break;
274 |
275 | default:
276 |
277 | if (![state parser:self shouldAcceptToken:tok]) {
278 | [self handleTokenNotExpectedHere: tok];
279 | return SBJsonStreamParserError;
280 | }
281 |
282 | switch (tok) {
283 | case sbjson_token_object_start:
284 | [self handleObjectStart];
285 | break;
286 |
287 | case sbjson_token_object_end:
288 | [self handleObjectEnd: tok];
289 | break;
290 |
291 | case sbjson_token_array_start:
292 | [self handleArrayStart];
293 | break;
294 |
295 | case sbjson_token_array_end:
296 | [self handleArrayEnd: tok];
297 | break;
298 |
299 | case sbjson_token_separator:
300 | case sbjson_token_keyval_separator:
301 | [state parser:self shouldTransitionTo:tok];
302 | break;
303 |
304 | case sbjson_token_true:
305 | [self parserFoundObject:kTrue];
306 | [state parser:self shouldTransitionTo:tok];
307 | break;
308 |
309 | case sbjson_token_false:
310 | [self parserFoundObject:kFalse];
311 | [state parser:self shouldTransitionTo:tok];
312 | break;
313 |
314 | case sbjson_token_null:
315 | [self parserFoundObject:kNull];
316 | [state parser:self shouldTransitionTo:tok];
317 | break;
318 |
319 | case sbjson_token_number:
320 | [self parserFoundObject:token];
321 | [state parser:self shouldTransitionTo:tok];
322 | break;
323 |
324 | case sbjson_token_string:
325 | if ([state needKey])
326 | [keyStack addObject:token];
327 | else
328 | [self parserFoundObject:token];
329 | [state parser:self shouldTransitionTo:tok];
330 | break;
331 |
332 | default:
333 | break;
334 | }
335 | break;
336 | }
337 | }
338 | return SBJsonStreamParserComplete;
339 | }
340 |
341 |
342 | @end
343 |
--------------------------------------------------------------------------------
/PSGoogleReader/SBJSON/SBJsonStreamParserAccumulator.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (C) 2011 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
31 | #import "SBJsonStreamParser.h"
32 |
33 | @interface SBJsonStreamParserAccumulator : NSObject
34 |
35 | @property (copy) id value;
36 |
37 | @end
38 |
--------------------------------------------------------------------------------
/PSGoogleReader/SBJSON/SBJsonStreamParserAccumulator.m:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (C) 2011 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 "SBJsonStreamParserAccumulator.h"
31 |
32 | @implementation SBJsonStreamParserAccumulator
33 |
34 | @synthesize value;
35 |
36 |
37 | #pragma mark SBJsonStreamParserDelegate
38 |
39 | - (void)parser:(SBJsonStreamParser*)parser foundArray:(NSArray *)array {
40 | value = array;
41 | }
42 |
43 | - (void)parser:(SBJsonStreamParser*)parser foundObject:(NSDictionary *)dict {
44 | value = dict;
45 | }
46 |
47 | @end
48 |
--------------------------------------------------------------------------------
/PSGoogleReader/SBJSON/SBJsonStreamParserState.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2010, Stig Brautaset.
3 | All rights reserved.
4 |
5 | Redistribution and use in source and binary forms, with or without
6 | modification, are permitted provided that the following conditions are
7 | met:
8 |
9 | Redistributions of source code must retain the above copyright
10 | notice, this list of conditions and the following disclaimer.
11 |
12 | Redistributions in binary form must reproduce the above copyright
13 | notice, this list of conditions and the following disclaimer in the
14 | documentation and/or other materials provided with the distribution.
15 |
16 | Neither the name of the the author nor the names of its contributors
17 | may be used to endorse or promote products derived from this software
18 | without specific prior written permission.
19 |
20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
21 | IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
23 | PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 | HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 | */
32 |
33 | #import
34 |
35 | #import "SBJsonTokeniser.h"
36 | #import "SBJsonStreamParser.h"
37 |
38 | @interface SBJsonStreamParserState : NSObject
39 | + (id)sharedInstance;
40 |
41 | - (BOOL)parser:(SBJsonStreamParser*)parser shouldAcceptToken:(sbjson_token_t)token;
42 | - (SBJsonStreamParserStatus)parserShouldReturn:(SBJsonStreamParser*)parser;
43 | - (void)parser:(SBJsonStreamParser*)parser shouldTransitionTo:(sbjson_token_t)tok;
44 | - (BOOL)needKey;
45 | - (BOOL)isError;
46 |
47 | - (NSString*)name;
48 |
49 | @end
50 |
51 | @interface SBJsonStreamParserStateStart : SBJsonStreamParserState
52 | @end
53 |
54 | @interface SBJsonStreamParserStateComplete : SBJsonStreamParserState
55 | @end
56 |
57 | @interface SBJsonStreamParserStateError : SBJsonStreamParserState
58 | @end
59 |
60 |
61 | @interface SBJsonStreamParserStateObjectStart : SBJsonStreamParserState
62 | @end
63 |
64 | @interface SBJsonStreamParserStateObjectGotKey : SBJsonStreamParserState
65 | @end
66 |
67 | @interface SBJsonStreamParserStateObjectSeparator : SBJsonStreamParserState
68 | @end
69 |
70 | @interface SBJsonStreamParserStateObjectGotValue : SBJsonStreamParserState
71 | @end
72 |
73 | @interface SBJsonStreamParserStateObjectNeedKey : SBJsonStreamParserState
74 | @end
75 |
76 | @interface SBJsonStreamParserStateArrayStart : SBJsonStreamParserState
77 | @end
78 |
79 | @interface SBJsonStreamParserStateArrayGotValue : SBJsonStreamParserState
80 | @end
81 |
82 | @interface SBJsonStreamParserStateArrayNeedValue : SBJsonStreamParserState
83 | @end
84 |
--------------------------------------------------------------------------------
/PSGoogleReader/SBJSON/SBJsonStreamParserState.m:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2010, Stig Brautaset.
3 | All rights reserved.
4 |
5 | Redistribution and use in source and binary forms, with or without
6 | modification, are permitted provided that the following conditions are
7 | met:
8 |
9 | Redistributions of source code must retain the above copyright
10 | notice, this list of conditions and the following disclaimer.
11 |
12 | Redistributions in binary form must reproduce the above copyright
13 | notice, this list of conditions and the following disclaimer in the
14 | documentation and/or other materials provided with the distribution.
15 |
16 | Neither the name of the the author nor the names of its contributors
17 | may be used to endorse or promote products derived from this software
18 | without specific prior written permission.
19 |
20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
21 | IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
23 | PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 | HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 | */
32 |
33 | #import "SBJsonStreamParserState.h"
34 | #import "SBJsonStreamParser.h"
35 |
36 | #define SINGLETON \
37 | + (id)sharedInstance { \
38 | static id state; \
39 | if (!state) state = [[self alloc] init]; \
40 | return state; \
41 | }
42 |
43 | @implementation SBJsonStreamParserState
44 |
45 | + (id)sharedInstance { return nil; }
46 |
47 | - (BOOL)parser:(SBJsonStreamParser*)parser shouldAcceptToken:(sbjson_token_t)token {
48 | return NO;
49 | }
50 |
51 | - (SBJsonStreamParserStatus)parserShouldReturn:(SBJsonStreamParser*)parser {
52 | return SBJsonStreamParserWaitingForData;
53 | }
54 |
55 | - (void)parser:(SBJsonStreamParser*)parser shouldTransitionTo:(sbjson_token_t)tok {}
56 |
57 | - (BOOL)needKey {
58 | return NO;
59 | }
60 |
61 | - (NSString*)name {
62 | return @"";
63 | }
64 |
65 | - (BOOL)isError {
66 | return NO;
67 | }
68 |
69 | @end
70 |
71 | #pragma mark -
72 |
73 | @implementation SBJsonStreamParserStateStart
74 |
75 | SINGLETON
76 |
77 | - (BOOL)parser:(SBJsonStreamParser*)parser shouldAcceptToken:(sbjson_token_t)token {
78 | return token == sbjson_token_array_start || token == sbjson_token_object_start;
79 | }
80 |
81 | - (void)parser:(SBJsonStreamParser*)parser shouldTransitionTo:(sbjson_token_t)tok {
82 |
83 | SBJsonStreamParserState *state = nil;
84 | switch (tok) {
85 | case sbjson_token_array_start:
86 | state = [SBJsonStreamParserStateArrayStart sharedInstance];
87 | break;
88 |
89 | case sbjson_token_object_start:
90 | state = [SBJsonStreamParserStateObjectStart sharedInstance];
91 | break;
92 |
93 | case sbjson_token_array_end:
94 | case sbjson_token_object_end:
95 | if (parser.supportMultipleDocuments)
96 | state = parser.state;
97 | else
98 | state = [SBJsonStreamParserStateComplete sharedInstance];
99 | break;
100 |
101 | case sbjson_token_eof:
102 | return;
103 |
104 | default:
105 | state = [SBJsonStreamParserStateError sharedInstance];
106 | break;
107 | }
108 |
109 |
110 | parser.state = state;
111 | }
112 |
113 | - (NSString*)name { return @"before outer-most array or object"; }
114 |
115 | @end
116 |
117 | #pragma mark -
118 |
119 | @implementation SBJsonStreamParserStateComplete
120 |
121 | SINGLETON
122 |
123 | - (NSString*)name { return @"after outer-most array or object"; }
124 |
125 | - (SBJsonStreamParserStatus)parserShouldReturn:(SBJsonStreamParser*)parser {
126 | return SBJsonStreamParserComplete;
127 | }
128 |
129 | @end
130 |
131 | #pragma mark -
132 |
133 | @implementation SBJsonStreamParserStateError
134 |
135 | SINGLETON
136 |
137 | - (NSString*)name { return @"in error"; }
138 |
139 | - (SBJsonStreamParserStatus)parserShouldReturn:(SBJsonStreamParser*)parser {
140 | return SBJsonStreamParserError;
141 | }
142 |
143 | - (BOOL)isError {
144 | return YES;
145 | }
146 |
147 | @end
148 |
149 | #pragma mark -
150 |
151 | @implementation SBJsonStreamParserStateObjectStart
152 |
153 | SINGLETON
154 |
155 | - (NSString*)name { return @"at beginning of object"; }
156 |
157 | - (BOOL)parser:(SBJsonStreamParser*)parser shouldAcceptToken:(sbjson_token_t)token {
158 | switch (token) {
159 | case sbjson_token_object_end:
160 | case sbjson_token_string:
161 | return YES;
162 | break;
163 | default:
164 | return NO;
165 | break;
166 | }
167 | }
168 |
169 | - (void)parser:(SBJsonStreamParser*)parser shouldTransitionTo:(sbjson_token_t)tok {
170 | parser.state = [SBJsonStreamParserStateObjectGotKey sharedInstance];
171 | }
172 |
173 | - (BOOL)needKey {
174 | return YES;
175 | }
176 |
177 | @end
178 |
179 | #pragma mark -
180 |
181 | @implementation SBJsonStreamParserStateObjectGotKey
182 |
183 | SINGLETON
184 |
185 | - (NSString*)name { return @"after object key"; }
186 |
187 | - (BOOL)parser:(SBJsonStreamParser*)parser shouldAcceptToken:(sbjson_token_t)token {
188 | return token == sbjson_token_keyval_separator;
189 | }
190 |
191 | - (void)parser:(SBJsonStreamParser*)parser shouldTransitionTo:(sbjson_token_t)tok {
192 | parser.state = [SBJsonStreamParserStateObjectSeparator sharedInstance];
193 | }
194 |
195 | @end
196 |
197 | #pragma mark -
198 |
199 | @implementation SBJsonStreamParserStateObjectSeparator
200 |
201 | SINGLETON
202 |
203 | - (NSString*)name { return @"as object value"; }
204 |
205 | - (BOOL)parser:(SBJsonStreamParser*)parser shouldAcceptToken:(sbjson_token_t)token {
206 | switch (token) {
207 | case sbjson_token_object_start:
208 | case sbjson_token_array_start:
209 | case sbjson_token_true:
210 | case sbjson_token_false:
211 | case sbjson_token_null:
212 | case sbjson_token_number:
213 | case sbjson_token_string:
214 | return YES;
215 | break;
216 |
217 | default:
218 | return NO;
219 | break;
220 | }
221 | }
222 |
223 | - (void)parser:(SBJsonStreamParser*)parser shouldTransitionTo:(sbjson_token_t)tok {
224 | parser.state = [SBJsonStreamParserStateObjectGotValue sharedInstance];
225 | }
226 |
227 | @end
228 |
229 | #pragma mark -
230 |
231 | @implementation SBJsonStreamParserStateObjectGotValue
232 |
233 | SINGLETON
234 |
235 | - (NSString*)name { return @"after object value"; }
236 |
237 | - (BOOL)parser:(SBJsonStreamParser*)parser shouldAcceptToken:(sbjson_token_t)token {
238 | switch (token) {
239 | case sbjson_token_object_end:
240 | case sbjson_token_separator:
241 | return YES;
242 | break;
243 | default:
244 | return NO;
245 | break;
246 | }
247 | }
248 |
249 | - (void)parser:(SBJsonStreamParser*)parser shouldTransitionTo:(sbjson_token_t)tok {
250 | parser.state = [SBJsonStreamParserStateObjectNeedKey sharedInstance];
251 | }
252 |
253 |
254 | @end
255 |
256 | #pragma mark -
257 |
258 | @implementation SBJsonStreamParserStateObjectNeedKey
259 |
260 | SINGLETON
261 |
262 | - (NSString*)name { return @"in place of object key"; }
263 |
264 | - (BOOL)parser:(SBJsonStreamParser*)parser shouldAcceptToken:(sbjson_token_t)token {
265 | return sbjson_token_string == token;
266 | }
267 |
268 | - (void)parser:(SBJsonStreamParser*)parser shouldTransitionTo:(sbjson_token_t)tok {
269 | parser.state = [SBJsonStreamParserStateObjectGotKey sharedInstance];
270 | }
271 |
272 | - (BOOL)needKey {
273 | return YES;
274 | }
275 |
276 | @end
277 |
278 | #pragma mark -
279 |
280 | @implementation SBJsonStreamParserStateArrayStart
281 |
282 | SINGLETON
283 |
284 | - (NSString*)name { return @"at array start"; }
285 |
286 | - (BOOL)parser:(SBJsonStreamParser*)parser shouldAcceptToken:(sbjson_token_t)token {
287 | switch (token) {
288 | case sbjson_token_object_end:
289 | case sbjson_token_keyval_separator:
290 | case sbjson_token_separator:
291 | return NO;
292 | break;
293 |
294 | default:
295 | return YES;
296 | break;
297 | }
298 | }
299 |
300 | - (void)parser:(SBJsonStreamParser*)parser shouldTransitionTo:(sbjson_token_t)tok {
301 | parser.state = [SBJsonStreamParserStateArrayGotValue sharedInstance];
302 | }
303 |
304 | @end
305 |
306 | #pragma mark -
307 |
308 | @implementation SBJsonStreamParserStateArrayGotValue
309 |
310 | SINGLETON
311 |
312 | - (NSString*)name { return @"after array value"; }
313 |
314 |
315 | - (BOOL)parser:(SBJsonStreamParser*)parser shouldAcceptToken:(sbjson_token_t)token {
316 | return token == sbjson_token_array_end || token == sbjson_token_separator;
317 | }
318 |
319 | - (void)parser:(SBJsonStreamParser*)parser shouldTransitionTo:(sbjson_token_t)tok {
320 | if (tok == sbjson_token_separator)
321 | parser.state = [SBJsonStreamParserStateArrayNeedValue sharedInstance];
322 | }
323 |
324 | @end
325 |
326 | #pragma mark -
327 |
328 | @implementation SBJsonStreamParserStateArrayNeedValue
329 |
330 | SINGLETON
331 |
332 | - (NSString*)name { return @"as array value"; }
333 |
334 |
335 | - (BOOL)parser:(SBJsonStreamParser*)parser shouldAcceptToken:(sbjson_token_t)token {
336 | switch (token) {
337 | case sbjson_token_array_end:
338 | case sbjson_token_keyval_separator:
339 | case sbjson_token_object_end:
340 | case sbjson_token_separator:
341 | return NO;
342 | break;
343 |
344 | default:
345 | return YES;
346 | break;
347 | }
348 | }
349 |
350 | - (void)parser:(SBJsonStreamParser*)parser shouldTransitionTo:(sbjson_token_t)tok {
351 | parser.state = [SBJsonStreamParserStateArrayGotValue sharedInstance];
352 | }
353 |
354 | @end
355 |
356 |
--------------------------------------------------------------------------------
/PSGoogleReader/SBJSON/SBJsonStreamWriter.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2010, Stig Brautaset.
3 | All rights reserved.
4 |
5 | Redistribution and use in source and binary forms, with or without
6 | modification, are permitted provided that the following conditions are
7 | met:
8 |
9 | Redistributions of source code must retain the above copyright
10 | notice, this list of conditions and the following disclaimer.
11 |
12 | Redistributions in binary form must reproduce the above copyright
13 | notice, this list of conditions and the following disclaimer in the
14 | documentation and/or other materials provided with the distribution.
15 |
16 | Neither the name of the the author nor the names of its contributors
17 | may be used to endorse or promote products derived from this software
18 | without specific prior written permission.
19 |
20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
21 | IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
23 | PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 | HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 | */
32 |
33 | #import
34 |
35 | /// Enable JSON writing for non-native objects
36 | @interface NSObject (SBProxyForJson)
37 |
38 | /**
39 | @brief Allows generation of JSON for otherwise unsupported classes.
40 |
41 | If you have a custom class that you want to create a JSON representation
42 | for you can implement this method in your class. It should return a
43 | representation of your object defined in terms of objects that can be
44 | translated into JSON. For example, a Person object might implement it like this:
45 |
46 | @code
47 | - (id)proxyForJson {
48 | return [NSDictionary dictionaryWithObjectsAndKeys:
49 | name, @"name",
50 | phone, @"phone",
51 | email, @"email",
52 | nil];
53 | }
54 | @endcode
55 |
56 | */
57 | - (id)proxyForJson;
58 |
59 | @end
60 |
61 | @class SBJsonStreamWriter;
62 |
63 | @protocol SBJsonStreamWriterDelegate
64 |
65 | - (void)writer:(SBJsonStreamWriter*)writer appendBytes:(const void *)bytes length:(NSUInteger)length;
66 |
67 | @end
68 |
69 | @class SBJsonStreamWriterState;
70 |
71 | /**
72 | @brief The Stream Writer class.
73 |
74 | Accepts a stream of messages and writes JSON of these to its delegate object.
75 |
76 | This class provides a range of high-, mid- and low-level methods. You can mix
77 | and match calls to these. For example, you may want to call -writeArrayOpen
78 | to start an array and then repeatedly call -writeObject: with various objects
79 | before finishing off with a -writeArrayClose call.
80 |
81 | @see @ref json2objc
82 |
83 | */
84 |
85 | @interface SBJsonStreamWriter : NSObject {
86 | NSMutableDictionary *cache;
87 | }
88 |
89 | @property (nonatomic, unsafe_unretained) SBJsonStreamWriterState *state; // Internal
90 | @property (nonatomic, readonly, strong) NSMutableArray *stateStack; // Internal
91 |
92 | /**
93 | @brief delegate to receive JSON output
94 | Delegate that will receive messages with output.
95 | */
96 | @property (unsafe_unretained) id delegate;
97 |
98 | /**
99 | @brief The maximum recursing depth.
100 |
101 | Defaults to 512. If the input is nested deeper than this the input will be deemed to be
102 | malicious and the parser returns nil, signalling an error. ("Nested too deep".) You can
103 | turn off this security feature by setting the maxDepth value to 0.
104 | */
105 | @property NSUInteger maxDepth;
106 |
107 | /**
108 | @brief Whether we are generating human-readable (multiline) JSON.
109 |
110 | Set whether or not to generate human-readable JSON. The default is NO, which produces
111 | JSON without any whitespace between tokens. If set to YES, generates human-readable
112 | JSON with linebreaks after each array value and dictionary key/value pair, indented two
113 | spaces per nesting level.
114 | */
115 | @property BOOL humanReadable;
116 |
117 | /**
118 | @brief Whether or not to sort the dictionary keys in the output.
119 |
120 | If this is set to YES, the dictionary keys in the JSON output will be in sorted order.
121 | (This is useful if you need to compare two structures, for example.) The default is NO.
122 | */
123 | @property BOOL sortKeys;
124 |
125 | /// Contains the error description after an error has occured.
126 | @property (copy) NSString *error;
127 |
128 | /**
129 | Write an NSDictionary to the JSON stream.
130 | @return YES if successful, or NO on failure
131 | */
132 | - (BOOL)writeObject:(NSDictionary*)dict;
133 |
134 | /**
135 | Write an NSArray to the JSON stream.
136 | @return YES if successful, or NO on failure
137 | */
138 | - (BOOL)writeArray:(NSArray *)array;
139 |
140 | /**
141 | Start writing an Object to the stream
142 | @return YES if successful, or NO on failure
143 | */
144 | - (BOOL)writeObjectOpen;
145 |
146 | /**
147 | Close the current object being written
148 | @return YES if successful, or NO on failure
149 | */
150 | - (BOOL)writeObjectClose;
151 |
152 | /** Start writing an Array to the stream
153 | @return YES if successful, or NO on failure
154 | */
155 | - (BOOL)writeArrayOpen;
156 |
157 | /** Close the current Array being written
158 | @return YES if successful, or NO on failure
159 | */
160 | - (BOOL)writeArrayClose;
161 |
162 | /** Write a null to the stream
163 | @return YES if successful, or NO on failure
164 | */
165 | - (BOOL)writeNull;
166 |
167 | /** Write a boolean to the stream
168 | @return YES if successful, or NO on failure
169 | */
170 | - (BOOL)writeBool:(BOOL)x;
171 |
172 | /** Write a Number to the stream
173 | @return YES if successful, or NO on failure
174 | */
175 | - (BOOL)writeNumber:(NSNumber*)n;
176 |
177 | /** Write a String to the stream
178 | @return YES if successful, or NO on failure
179 | */
180 | - (BOOL)writeString:(NSString*)s;
181 |
182 | @end
183 |
184 | @interface SBJsonStreamWriter (Private)
185 | - (BOOL)writeValue:(id)v;
186 | - (void)appendBytes:(const void *)bytes length:(NSUInteger)length;
187 | @end
188 |
189 |
--------------------------------------------------------------------------------
/PSGoogleReader/SBJSON/SBJsonStreamWriter.m:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2010, Stig Brautaset.
3 | All rights reserved.
4 |
5 | Redistribution and use in source and binary forms, with or without
6 | modification, are permitted provided that the following conditions are
7 | met:
8 |
9 | Redistributions of source code must retain the above copyright
10 | notice, this list of conditions and the following disclaimer.
11 |
12 | Redistributions in binary form must reproduce the above copyright
13 | notice, this list of conditions and the following disclaimer in the
14 | documentation and/or other materials provided with the distribution.
15 |
16 | Neither the name of the the author nor the names of its contributors
17 | may be used to endorse or promote products derived from this software
18 | without specific prior written permission.
19 |
20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
21 | IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
23 | PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 | HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 | */
32 |
33 | #import "SBJsonStreamWriter.h"
34 | #import "SBJsonStreamWriterState.h"
35 |
36 | static NSNumber *kNotANumber;
37 | static NSNumber *kTrue;
38 | static NSNumber *kFalse;
39 | static NSNumber *kPositiveInfinity;
40 | static NSNumber *kNegativeInfinity;
41 |
42 |
43 | @implementation SBJsonStreamWriter
44 |
45 | @synthesize error;
46 | @synthesize maxDepth;
47 | @synthesize state;
48 | @synthesize stateStack;
49 | @synthesize humanReadable;
50 | @synthesize sortKeys;
51 |
52 | + (void)initialize {
53 | kNotANumber = [NSDecimalNumber notANumber];
54 | kPositiveInfinity = [NSNumber numberWithDouble:+INFINITY];
55 | kNegativeInfinity = [NSNumber numberWithDouble:-INFINITY];
56 | kTrue = [NSNumber numberWithBool:YES];
57 | kFalse = [NSNumber numberWithBool:NO];
58 | }
59 |
60 | #pragma mark Housekeeping
61 |
62 | @synthesize delegate;
63 |
64 | - (id)init {
65 | self = [super init];
66 | if (self) {
67 | maxDepth = 32u;
68 | stateStack = [[NSMutableArray alloc] initWithCapacity:maxDepth];
69 | state = [SBJsonStreamWriterStateStart sharedInstance];
70 | cache = [[NSMutableDictionary alloc] initWithCapacity:32];
71 | }
72 | return self;
73 | }
74 |
75 | - (void)dealloc {
76 | self.state = nil;
77 | }
78 |
79 | #pragma mark Methods
80 |
81 | - (void)appendBytes:(const void *)bytes length:(NSUInteger)length {
82 | [delegate writer:self appendBytes:bytes length:length];
83 | }
84 |
85 | - (BOOL)writeObject:(NSDictionary *)dict {
86 | if (![self writeObjectOpen])
87 | return NO;
88 |
89 | NSArray *keys = [dict allKeys];
90 | if (sortKeys)
91 | keys = [keys sortedArrayUsingSelector:@selector(compare:)];
92 |
93 | for (id k in keys) {
94 | if (![k isKindOfClass:[NSString class]]) {
95 | self.error = [NSString stringWithFormat:@"JSON object key must be string: %@", k];
96 | return NO;
97 | }
98 |
99 | if (![self writeString:k])
100 | return NO;
101 | if (![self writeValue:[dict objectForKey:k]])
102 | return NO;
103 | }
104 |
105 | return [self writeObjectClose];
106 | }
107 |
108 | - (BOOL)writeArray:(NSArray*)array {
109 | if (![self writeArrayOpen])
110 | return NO;
111 | for (id v in array)
112 | if (![self writeValue:v])
113 | return NO;
114 | return [self writeArrayClose];
115 | }
116 |
117 |
118 | - (BOOL)writeObjectOpen {
119 | if ([state isInvalidState:self]) return NO;
120 | if ([state expectingKey:self]) return NO;
121 | [state appendSeparator:self];
122 | if (humanReadable && stateStack.count) [state appendWhitespace:self];
123 |
124 | [stateStack addObject:state];
125 | self.state = [SBJsonStreamWriterStateObjectStart sharedInstance];
126 |
127 | if (maxDepth && stateStack.count > maxDepth) {
128 | self.error = @"Nested too deep";
129 | return NO;
130 | }
131 |
132 | [delegate writer:self appendBytes:"{" length:1];
133 | return YES;
134 | }
135 |
136 | - (BOOL)writeObjectClose {
137 | if ([state isInvalidState:self]) return NO;
138 |
139 | SBJsonStreamWriterState *prev = state;
140 |
141 | self.state = [stateStack lastObject];
142 | [stateStack removeLastObject];
143 |
144 | if (humanReadable) [prev appendWhitespace:self];
145 | [delegate writer:self appendBytes:"}" length:1];
146 |
147 | [state transitionState:self];
148 | return YES;
149 | }
150 |
151 | - (BOOL)writeArrayOpen {
152 | if ([state isInvalidState:self]) return NO;
153 | if ([state expectingKey:self]) return NO;
154 | [state appendSeparator:self];
155 | if (humanReadable && stateStack.count) [state appendWhitespace:self];
156 |
157 | [stateStack addObject:state];
158 | self.state = [SBJsonStreamWriterStateArrayStart sharedInstance];
159 |
160 | if (maxDepth && stateStack.count > maxDepth) {
161 | self.error = @"Nested too deep";
162 | return NO;
163 | }
164 |
165 | [delegate writer:self appendBytes:"[" length:1];
166 | return YES;
167 | }
168 |
169 | - (BOOL)writeArrayClose {
170 | if ([state isInvalidState:self]) return NO;
171 | if ([state expectingKey:self]) return NO;
172 |
173 | SBJsonStreamWriterState *prev = state;
174 |
175 | self.state = [stateStack lastObject];
176 | [stateStack removeLastObject];
177 |
178 | if (humanReadable) [prev appendWhitespace:self];
179 | [delegate writer:self appendBytes:"]" length:1];
180 |
181 | [state transitionState:self];
182 | return YES;
183 | }
184 |
185 | - (BOOL)writeNull {
186 | if ([state isInvalidState:self]) return NO;
187 | if ([state expectingKey:self]) return NO;
188 | [state appendSeparator:self];
189 | if (humanReadable) [state appendWhitespace:self];
190 |
191 | [delegate writer:self appendBytes:"null" length:4];
192 | [state transitionState:self];
193 | return YES;
194 | }
195 |
196 | - (BOOL)writeBool:(BOOL)x {
197 | if ([state isInvalidState:self]) return NO;
198 | if ([state expectingKey:self]) return NO;
199 | [state appendSeparator:self];
200 | if (humanReadable) [state appendWhitespace:self];
201 |
202 | if (x)
203 | [delegate writer:self appendBytes:"true" length:4];
204 | else
205 | [delegate writer:self appendBytes:"false" length:5];
206 | [state transitionState:self];
207 | return YES;
208 | }
209 |
210 |
211 | - (BOOL)writeValue:(id)o {
212 | if ([o isKindOfClass:[NSDictionary class]]) {
213 | return [self writeObject:o];
214 |
215 | } else if ([o isKindOfClass:[NSArray class]]) {
216 | return [self writeArray:o];
217 |
218 | } else if ([o isKindOfClass:[NSString class]]) {
219 | [self writeString:o];
220 | return YES;
221 |
222 | } else if ([o isKindOfClass:[NSNumber class]]) {
223 | return [self writeNumber:o];
224 |
225 | } else if ([o isKindOfClass:[NSNull class]]) {
226 | return [self writeNull];
227 |
228 | } else if ([o respondsToSelector:@selector(proxyForJson)]) {
229 | return [self writeValue:[o proxyForJson]];
230 |
231 | }
232 |
233 | self.error = [NSString stringWithFormat:@"JSON serialisation not supported for %@", [o class]];
234 | return NO;
235 | }
236 |
237 | static const char *strForChar(int c) {
238 | switch (c) {
239 | case 0: return "\\u0000"; break;
240 | case 1: return "\\u0001"; break;
241 | case 2: return "\\u0002"; break;
242 | case 3: return "\\u0003"; break;
243 | case 4: return "\\u0004"; break;
244 | case 5: return "\\u0005"; break;
245 | case 6: return "\\u0006"; break;
246 | case 7: return "\\u0007"; break;
247 | case 8: return "\\b"; break;
248 | case 9: return "\\t"; break;
249 | case 10: return "\\n"; break;
250 | case 11: return "\\u000b"; break;
251 | case 12: return "\\f"; break;
252 | case 13: return "\\r"; break;
253 | case 14: return "\\u000e"; break;
254 | case 15: return "\\u000f"; break;
255 | case 16: return "\\u0010"; break;
256 | case 17: return "\\u0011"; break;
257 | case 18: return "\\u0012"; break;
258 | case 19: return "\\u0013"; break;
259 | case 20: return "\\u0014"; break;
260 | case 21: return "\\u0015"; break;
261 | case 22: return "\\u0016"; break;
262 | case 23: return "\\u0017"; break;
263 | case 24: return "\\u0018"; break;
264 | case 25: return "\\u0019"; break;
265 | case 26: return "\\u001a"; break;
266 | case 27: return "\\u001b"; break;
267 | case 28: return "\\u001c"; break;
268 | case 29: return "\\u001d"; break;
269 | case 30: return "\\u001e"; break;
270 | case 31: return "\\u001f"; break;
271 | case 34: return "\\\""; break;
272 | case 92: return "\\\\"; break;
273 | }
274 | NSLog(@"FUTFUTFUT: -->'%c'<---", c);
275 | return "FUTFUTFUT";
276 | }
277 |
278 | - (BOOL)writeString:(NSString*)string {
279 | if ([state isInvalidState:self]) return NO;
280 | [state appendSeparator:self];
281 | if (humanReadable) [state appendWhitespace:self];
282 |
283 | NSMutableData *buf = [cache objectForKey:string];
284 | if (!buf) {
285 |
286 | NSUInteger len = [string lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
287 | const char *utf8 = [string UTF8String];
288 | NSUInteger written = 0, i = 0;
289 |
290 | buf = [NSMutableData dataWithCapacity:(NSUInteger)(len * 1.1f)];
291 | [buf appendBytes:"\"" length:1];
292 |
293 | for (i = 0; i < len; i++) {
294 | int c = utf8[i];
295 | BOOL isControlChar = c >= 0 && c < 32;
296 | if (isControlChar || c == '"' || c == '\\') {
297 | if (i - written)
298 | [buf appendBytes:utf8 + written length:i - written];
299 | written = i + 1;
300 |
301 | const char *t = strForChar(c);
302 | [buf appendBytes:t length:strlen(t)];
303 | }
304 | }
305 |
306 | if (i - written)
307 | [buf appendBytes:utf8 + written length:i - written];
308 |
309 | [buf appendBytes:"\"" length:1];
310 | [cache setObject:buf forKey:string];
311 | }
312 |
313 | [delegate writer:self appendBytes:[buf bytes] length:[buf length]];
314 | [state transitionState:self];
315 | return YES;
316 | }
317 |
318 | - (BOOL)writeNumber:(NSNumber*)number {
319 | if (number == kTrue || number == kFalse)
320 | return [self writeBool:[number boolValue]];
321 |
322 | if ([state isInvalidState:self]) return NO;
323 | if ([state expectingKey:self]) return NO;
324 | [state appendSeparator:self];
325 | if (humanReadable) [state appendWhitespace:self];
326 |
327 | if ([kPositiveInfinity isEqualToNumber:number]) {
328 | self.error = @"+Infinity is not a valid number in JSON";
329 | return NO;
330 |
331 | } else if ([kNegativeInfinity isEqualToNumber:number]) {
332 | self.error = @"-Infinity is not a valid number in JSON";
333 | return NO;
334 |
335 | } else if ([kNotANumber isEqualToNumber:number]) {
336 | self.error = @"NaN is not a valid number in JSON";
337 | return NO;
338 | }
339 |
340 | const char *objcType = [number objCType];
341 | char num[128];
342 | size_t len;
343 |
344 | switch (objcType[0]) {
345 | case 'c': case 'i': case 's': case 'l': case 'q':
346 | len = snprintf(num, sizeof num, "%lld", [number longLongValue]);
347 | break;
348 | case 'C': case 'I': case 'S': case 'L': case 'Q':
349 | len = snprintf(num, sizeof num, "%llu", [number unsignedLongLongValue]);
350 | break;
351 | case 'f': case 'd': default:
352 | if ([number isKindOfClass:[NSDecimalNumber class]]) {
353 | char const *utf8 = [[number stringValue] UTF8String];
354 | [delegate writer:self appendBytes:utf8 length: strlen(utf8)];
355 | [state transitionState:self];
356 | return YES;
357 | }
358 | len = snprintf(num, sizeof num, "%.17g", [number doubleValue]);
359 | break;
360 | }
361 | [delegate writer:self appendBytes:num length: len];
362 | [state transitionState:self];
363 | return YES;
364 | }
365 |
366 | @end
367 |
--------------------------------------------------------------------------------
/PSGoogleReader/SBJSON/SBJsonStreamWriterAccumulator.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (C) 2011 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 "SBJsonStreamWriter.h"
31 |
32 | @interface SBJsonStreamWriterAccumulator : NSObject
33 |
34 | @property (readonly, copy) NSMutableData* data;
35 |
36 | @end
37 |
--------------------------------------------------------------------------------
/PSGoogleReader/SBJSON/SBJsonStreamWriterAccumulator.m:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (C) 2011 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 "SBJsonStreamWriterAccumulator.h"
31 |
32 |
33 | @implementation SBJsonStreamWriterAccumulator
34 |
35 | @synthesize data;
36 |
37 | - (id)init {
38 | self = [super init];
39 | if (self) {
40 | data = [[NSMutableData alloc] initWithCapacity:8096u];
41 | }
42 | return self;
43 | }
44 |
45 |
46 | #pragma mark SBJsonStreamWriterDelegate
47 |
48 | - (void)writer:(SBJsonStreamWriter *)writer appendBytes:(const void *)bytes length:(NSUInteger)length {
49 | [data appendBytes:bytes length:length];
50 | }
51 |
52 | @end
53 |
--------------------------------------------------------------------------------
/PSGoogleReader/SBJSON/SBJsonStreamWriterState.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2010, Stig Brautaset.
3 | All rights reserved.
4 |
5 | Redistribution and use in source and binary forms, with or without
6 | modification, are permitted provided that the following conditions are
7 | met:
8 |
9 | Redistributions of source code must retain the above copyright
10 | notice, this list of conditions and the following disclaimer.
11 |
12 | Redistributions in binary form must reproduce the above copyright
13 | notice, this list of conditions and the following disclaimer in the
14 | documentation and/or other materials provided with the distribution.
15 |
16 | Neither the name of the the author nor the names of its contributors
17 | may be used to endorse or promote products derived from this software
18 | without specific prior written permission.
19 |
20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
21 | IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
23 | PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 | HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 | */
32 |
33 | #import
34 |
35 | @class SBJsonStreamWriter;
36 |
37 | @interface SBJsonStreamWriterState : NSObject
38 | + (id)sharedInstance;
39 | - (BOOL)isInvalidState:(SBJsonStreamWriter*)writer;
40 | - (void)appendSeparator:(SBJsonStreamWriter*)writer;
41 | - (BOOL)expectingKey:(SBJsonStreamWriter*)writer;
42 | - (void)transitionState:(SBJsonStreamWriter*)writer;
43 | - (void)appendWhitespace:(SBJsonStreamWriter*)writer;
44 | @end
45 |
46 | @interface SBJsonStreamWriterStateObjectStart : SBJsonStreamWriterState
47 | @end
48 |
49 | @interface SBJsonStreamWriterStateObjectKey : SBJsonStreamWriterStateObjectStart
50 | @end
51 |
52 | @interface SBJsonStreamWriterStateObjectValue : SBJsonStreamWriterState
53 | @end
54 |
55 | @interface SBJsonStreamWriterStateArrayStart : SBJsonStreamWriterState
56 | @end
57 |
58 | @interface SBJsonStreamWriterStateArrayValue : SBJsonStreamWriterState
59 | @end
60 |
61 | @interface SBJsonStreamWriterStateStart : SBJsonStreamWriterState
62 | @end
63 |
64 | @interface SBJsonStreamWriterStateComplete : SBJsonStreamWriterState
65 | @end
66 |
67 | @interface SBJsonStreamWriterStateError : SBJsonStreamWriterState
68 | @end
69 |
70 |
--------------------------------------------------------------------------------
/PSGoogleReader/SBJSON/SBJsonStreamWriterState.m:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2010, Stig Brautaset.
3 | All rights reserved.
4 |
5 | Redistribution and use in source and binary forms, with or without
6 | modification, are permitted provided that the following conditions are
7 | met:
8 |
9 | Redistributions of source code must retain the above copyright
10 | notice, this list of conditions and the following disclaimer.
11 |
12 | Redistributions in binary form must reproduce the above copyright
13 | notice, this list of conditions and the following disclaimer in the
14 | documentation and/or other materials provided with the distribution.
15 |
16 | Neither the name of the the author nor the names of its contributors
17 | may be used to endorse or promote products derived from this software
18 | without specific prior written permission.
19 |
20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
21 | IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
23 | PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 | HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 | */
32 |
33 | #import "SBJsonStreamWriterState.h"
34 | #import "SBJsonStreamWriter.h"
35 |
36 | #define SINGLETON \
37 | + (id)sharedInstance { \
38 | static id state; \
39 | if (!state) state = [[self alloc] init]; \
40 | return state; \
41 | }
42 |
43 |
44 | @implementation SBJsonStreamWriterState
45 | + (id)sharedInstance { return nil; }
46 | - (BOOL)isInvalidState:(SBJsonStreamWriter*)writer { return NO; }
47 | - (void)appendSeparator:(SBJsonStreamWriter*)writer {}
48 | - (BOOL)expectingKey:(SBJsonStreamWriter*)writer { return NO; }
49 | - (void)transitionState:(SBJsonStreamWriter *)writer {}
50 | - (void)appendWhitespace:(SBJsonStreamWriter*)writer {
51 | [writer appendBytes:"\n" length:1];
52 | for (NSUInteger i = 0; i < writer.stateStack.count; i++)
53 | [writer appendBytes:" " length:2];
54 | }
55 | @end
56 |
57 | @implementation SBJsonStreamWriterStateObjectStart
58 |
59 | SINGLETON
60 |
61 | - (void)transitionState:(SBJsonStreamWriter *)writer {
62 | writer.state = [SBJsonStreamWriterStateObjectValue sharedInstance];
63 | }
64 | - (BOOL)expectingKey:(SBJsonStreamWriter *)writer {
65 | writer.error = @"JSON object key must be string";
66 | return YES;
67 | }
68 | @end
69 |
70 | @implementation SBJsonStreamWriterStateObjectKey
71 |
72 | SINGLETON
73 |
74 | - (void)appendSeparator:(SBJsonStreamWriter *)writer {
75 | [writer appendBytes:"," length:1];
76 | }
77 | @end
78 |
79 | @implementation SBJsonStreamWriterStateObjectValue
80 |
81 | SINGLETON
82 |
83 | - (void)appendSeparator:(SBJsonStreamWriter *)writer {
84 | [writer appendBytes:":" length:1];
85 | }
86 | - (void)transitionState:(SBJsonStreamWriter *)writer {
87 | writer.state = [SBJsonStreamWriterStateObjectKey sharedInstance];
88 | }
89 | - (void)appendWhitespace:(SBJsonStreamWriter *)writer {
90 | [writer appendBytes:" " length:1];
91 | }
92 | @end
93 |
94 | @implementation SBJsonStreamWriterStateArrayStart
95 |
96 | SINGLETON
97 |
98 | - (void)transitionState:(SBJsonStreamWriter *)writer {
99 | writer.state = [SBJsonStreamWriterStateArrayValue sharedInstance];
100 | }
101 | @end
102 |
103 | @implementation SBJsonStreamWriterStateArrayValue
104 |
105 | SINGLETON
106 |
107 | - (void)appendSeparator:(SBJsonStreamWriter *)writer {
108 | [writer appendBytes:"," length:1];
109 | }
110 | @end
111 |
112 | @implementation SBJsonStreamWriterStateStart
113 |
114 | SINGLETON
115 |
116 |
117 | - (void)transitionState:(SBJsonStreamWriter *)writer {
118 | writer.state = [SBJsonStreamWriterStateComplete sharedInstance];
119 | }
120 | - (void)appendSeparator:(SBJsonStreamWriter *)writer {
121 | }
122 | @end
123 |
124 | @implementation SBJsonStreamWriterStateComplete
125 |
126 | SINGLETON
127 |
128 | - (BOOL)isInvalidState:(SBJsonStreamWriter*)writer {
129 | writer.error = @"Stream is closed";
130 | return YES;
131 | }
132 | @end
133 |
134 | @implementation SBJsonStreamWriterStateError
135 |
136 | SINGLETON
137 |
138 | @end
139 |
140 |
--------------------------------------------------------------------------------
/PSGoogleReader/SBJSON/SBJsonTokeniser.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2010, Stig Brautaset.
3 | All rights reserved.
4 |
5 | Redistribution and use in source and binary forms, with or without
6 | modification, are permitted provided that the following conditions are
7 | met:
8 |
9 | Redistributions of source code must retain the above copyright
10 | notice, this list of conditions and the following disclaimer.
11 |
12 | Redistributions in binary form must reproduce the above copyright
13 | notice, this list of conditions and the following disclaimer in the
14 | documentation and/or other materials provided with the distribution.
15 |
16 | Neither the name of the the author nor the names of its contributors
17 | may be used to endorse or promote products derived from this software
18 | without specific prior written permission.
19 |
20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
21 | IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
23 | PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 | HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 | */
32 |
33 | #import
34 |
35 | typedef enum {
36 | sbjson_token_error = -1,
37 | sbjson_token_eof,
38 |
39 | sbjson_token_array_start,
40 | sbjson_token_array_end,
41 |
42 | sbjson_token_object_start,
43 | sbjson_token_object_end,
44 |
45 | sbjson_token_separator,
46 | sbjson_token_keyval_separator,
47 |
48 | sbjson_token_number,
49 | sbjson_token_string,
50 | sbjson_token_true,
51 | sbjson_token_false,
52 | sbjson_token_null,
53 |
54 | } sbjson_token_t;
55 |
56 | @class SBJsonUTF8Stream;
57 |
58 | @interface SBJsonTokeniser : NSObject
59 |
60 | @property (strong) SBJsonUTF8Stream *stream;
61 | @property (copy) NSString *error;
62 |
63 | - (void)appendData:(NSData*)data_;
64 |
65 | - (sbjson_token_t)getToken:(NSObject**)token;
66 |
67 | @end
68 |
--------------------------------------------------------------------------------
/PSGoogleReader/SBJSON/SBJsonTokeniser.m:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2010-2011, 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
6 | met:
7 |
8 | Redistributions of source code must retain the above copyright
9 | notice, this list of conditions and the following disclaimer.
10 |
11 | Redistributions in binary form must reproduce the above copyright
12 | notice, this list of conditions and the following disclaimer in the
13 | documentation and/or other materials provided with the distribution.
14 |
15 | Neither the name of the the author nor the names of its contributors
16 | may be used to endorse or promote products derived from this software
17 | without specific prior written permission.
18 |
19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
20 | IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
22 | PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 | HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 | */
31 |
32 | #import "SBJsonTokeniser.h"
33 | #import "SBJsonUTF8Stream.h"
34 |
35 | #define SBStringIsIllegalSurrogateHighCharacter(character) (((character) >= 0xD800UL) && ((character) <= 0xDFFFUL))
36 | #define SBStringIsSurrogateLowCharacter(character) ((character >= 0xDC00UL) && (character <= 0xDFFFUL))
37 | #define SBStringIsSurrogateHighCharacter(character) ((character >= 0xD800UL) && (character <= 0xDBFFUL))
38 |
39 | @implementation SBJsonTokeniser
40 |
41 | @synthesize error = _error;
42 | @synthesize stream = _stream;
43 |
44 | - (id)init {
45 | self = [super init];
46 | if (self) {
47 | _stream = [[SBJsonUTF8Stream alloc] init];
48 |
49 | }
50 |
51 | return self;
52 | }
53 |
54 |
55 | - (void)appendData:(NSData *)data_ {
56 | [_stream appendData:data_];
57 | }
58 |
59 |
60 | - (sbjson_token_t)match:(const char *)pattern length:(NSUInteger)len retval:(sbjson_token_t)token {
61 | if (![_stream haveRemainingCharacters:len])
62 | return sbjson_token_eof;
63 |
64 | if ([_stream skipCharacters:pattern length:len])
65 | return token;
66 |
67 | self.error = [NSString stringWithFormat:@"Expected '%s' after initial '%.1s'", pattern, pattern];
68 | return sbjson_token_error;
69 | }
70 |
71 | - (BOOL)decodeEscape:(unichar)ch into:(unichar*)decoded {
72 | switch (ch) {
73 | case '\\':
74 | case '/':
75 | case '"':
76 | *decoded = ch;
77 | break;
78 |
79 | case 'b':
80 | *decoded = '\b';
81 | break;
82 |
83 | case 'n':
84 | *decoded = '\n';
85 | break;
86 |
87 | case 'r':
88 | *decoded = '\r';
89 | break;
90 |
91 | case 't':
92 | *decoded = '\t';
93 | break;
94 |
95 | case 'f':
96 | *decoded = '\f';
97 | break;
98 |
99 | default:
100 | self.error = @"Illegal escape character";
101 | return NO;
102 | break;
103 | }
104 | return YES;
105 | }
106 |
107 | - (BOOL)decodeHexQuad:(unichar*)quad {
108 | unichar c, tmp = 0;
109 |
110 | for (int i = 0; i < 4; i++) {
111 | (void)[_stream getNextUnichar:&c];
112 | tmp *= 16;
113 | switch (c) {
114 | case '0' ... '9':
115 | tmp += c - '0';
116 | break;
117 |
118 | case 'a' ... 'f':
119 | tmp += 10 + c - 'a';
120 | break;
121 |
122 | case 'A' ... 'F':
123 | tmp += 10 + c - 'A';
124 | break;
125 |
126 | default:
127 | return NO;
128 | }
129 | }
130 | *quad = tmp;
131 | return YES;
132 | }
133 |
134 | - (sbjson_token_t)getStringToken:(NSObject**)token {
135 | NSMutableString *acc = nil;
136 |
137 | for (;;) {
138 | [_stream skip];
139 |
140 | unichar ch;
141 | {
142 | NSMutableString *string = nil;
143 | if (![_stream getSimpleString:&string])
144 | return sbjson_token_eof;
145 |
146 | if (!string) {
147 | self.error = @"Broken Unicode encoding";
148 | return sbjson_token_error;
149 | }
150 |
151 |
152 | if (![_stream getUnichar:&ch])
153 | return sbjson_token_eof;
154 |
155 | if (acc) {
156 | [acc appendString:string];
157 |
158 | } else if (ch == '"') {
159 | *token = string;
160 | [_stream skip];
161 | return sbjson_token_string;
162 |
163 | } else {
164 | acc = [string mutableCopy];
165 | }
166 | }
167 |
168 | switch (ch) {
169 | case 0 ... 0x1F:
170 | self.error = [NSString stringWithFormat:@"Unescaped control character [0x%0.2X]", (int)ch];
171 | return sbjson_token_error;
172 | break;
173 |
174 | case '"':
175 | *token = acc;
176 | [_stream skip];
177 | return sbjson_token_string;
178 | break;
179 |
180 | case '\\':
181 | if (![_stream getNextUnichar:&ch])
182 | return sbjson_token_eof;
183 |
184 | if (ch == 'u') {
185 | if (![_stream haveRemainingCharacters:5])
186 | return sbjson_token_eof;
187 |
188 | unichar hi;
189 | if (![self decodeHexQuad:&hi]) {
190 | self.error = @"Invalid hex quad";
191 | return sbjson_token_error;
192 | }
193 |
194 | if (SBStringIsSurrogateHighCharacter(hi)) {
195 | unichar lo;
196 |
197 | if (![_stream haveRemainingCharacters:6])
198 | return sbjson_token_eof;
199 |
200 | (void)[_stream getNextUnichar:&ch];
201 | (void)[_stream getNextUnichar:&lo];
202 | if (ch != '\\' || lo != 'u' || ![self decodeHexQuad:&lo]) {
203 | self.error = @"Missing low character in surrogate pair";
204 | return sbjson_token_error;
205 | }
206 |
207 | if (!SBStringIsSurrogateLowCharacter(lo)) {
208 | self.error = @"Invalid low character in surrogate pair";
209 | return sbjson_token_error;
210 | }
211 |
212 | [acc appendFormat:@"%C%C", hi, lo];
213 | } else if (SBStringIsIllegalSurrogateHighCharacter(hi)) {
214 | self.error = @"Invalid high character in surrogate pair";
215 | return sbjson_token_error;
216 | } else {
217 | [acc appendFormat:@"%C", hi];
218 | }
219 |
220 |
221 | } else {
222 | unichar decoded;
223 | if (![self decodeEscape:ch into:&decoded])
224 | return sbjson_token_error;
225 | [acc appendFormat:@"%C", decoded];
226 | }
227 |
228 | break;
229 |
230 | default: {
231 | self.error = [NSString stringWithFormat:@"Invalid UTF-8: '%x'", (int)ch];
232 | return sbjson_token_error;
233 | break;
234 | }
235 | }
236 | }
237 | return sbjson_token_eof;
238 | }
239 |
240 | - (sbjson_token_t)getNumberToken:(NSObject**)token {
241 |
242 | NSUInteger numberStart = _stream.index;
243 | NSCharacterSet *digits = [NSCharacterSet decimalDigitCharacterSet];
244 |
245 | unichar ch;
246 | if (![_stream getUnichar:&ch])
247 | return sbjson_token_eof;
248 |
249 | BOOL isNegative = NO;
250 | if (ch == '-') {
251 | isNegative = YES;
252 | if (![_stream getNextUnichar:&ch])
253 | return sbjson_token_eof;
254 | }
255 |
256 | unsigned long long mantissa = 0;
257 | int mantissa_length = 0;
258 |
259 | if (ch == '0') {
260 | mantissa_length++;
261 | if (![_stream getNextUnichar:&ch])
262 | return sbjson_token_eof;
263 |
264 | if ([digits characterIsMember:ch]) {
265 | self.error = @"Leading zero is illegal in number";
266 | return sbjson_token_error;
267 | }
268 | }
269 |
270 | while ([digits characterIsMember:ch]) {
271 | mantissa *= 10;
272 | mantissa += (ch - '0');
273 | mantissa_length++;
274 |
275 | if (![_stream getNextUnichar:&ch])
276 | return sbjson_token_eof;
277 | }
278 |
279 | short exponent = 0;
280 | BOOL isFloat = NO;
281 |
282 | if (ch == '.') {
283 | isFloat = YES;
284 | if (![_stream getNextUnichar:&ch])
285 | return sbjson_token_eof;
286 |
287 | while ([digits characterIsMember:ch]) {
288 | mantissa *= 10;
289 | mantissa += (ch - '0');
290 | mantissa_length++;
291 | exponent--;
292 |
293 | if (![_stream getNextUnichar:&ch])
294 | return sbjson_token_eof;
295 | }
296 |
297 | if (!exponent) {
298 | self.error = @"No digits after decimal point";
299 | return sbjson_token_error;
300 | }
301 | }
302 |
303 | BOOL hasExponent = NO;
304 | if (ch == 'e' || ch == 'E') {
305 | hasExponent = YES;
306 |
307 | if (![_stream getNextUnichar:&ch])
308 | return sbjson_token_eof;
309 |
310 | BOOL expIsNegative = NO;
311 | if (ch == '-') {
312 | expIsNegative = YES;
313 | if (![_stream getNextUnichar:&ch])
314 | return sbjson_token_eof;
315 |
316 | } else if (ch == '+') {
317 | if (![_stream getNextUnichar:&ch])
318 | return sbjson_token_eof;
319 | }
320 |
321 | short explicit_exponent = 0;
322 | short explicit_exponent_length = 0;
323 | while ([digits characterIsMember:ch]) {
324 | explicit_exponent *= 10;
325 | explicit_exponent += (ch - '0');
326 | explicit_exponent_length++;
327 |
328 | if (![_stream getNextUnichar:&ch])
329 | return sbjson_token_eof;
330 | }
331 |
332 | if (explicit_exponent_length == 0) {
333 | self.error = @"No digits in exponent";
334 | return sbjson_token_error;
335 | }
336 |
337 | if (expIsNegative)
338 | exponent -= explicit_exponent;
339 | else
340 | exponent += explicit_exponent;
341 | }
342 |
343 | if (!mantissa_length && isNegative) {
344 | self.error = @"No digits after initial minus";
345 | return sbjson_token_error;
346 |
347 | } else if (mantissa_length >= 19) {
348 |
349 | NSString *number = [_stream stringWithRange:NSMakeRange(numberStart, _stream.index - numberStart)];
350 | *token = [NSDecimalNumber decimalNumberWithString:number];
351 |
352 | } else if (!isFloat && !hasExponent) {
353 | if (!isNegative)
354 | *token = [NSNumber numberWithUnsignedLongLong:mantissa];
355 | else
356 | *token = [NSNumber numberWithLongLong:-mantissa];
357 | } else {
358 | *token = [NSDecimalNumber decimalNumberWithMantissa:mantissa
359 | exponent:exponent
360 | isNegative:isNegative];
361 | }
362 |
363 | return sbjson_token_number;
364 | }
365 |
366 | - (sbjson_token_t)getToken:(NSObject **)token {
367 |
368 | [_stream skipWhitespace];
369 |
370 | unichar ch;
371 | if (![_stream getUnichar:&ch])
372 | return sbjson_token_eof;
373 |
374 | NSUInteger oldIndexLocation = _stream.index;
375 | sbjson_token_t tok;
376 |
377 | switch (ch) {
378 | case '[':
379 | tok = sbjson_token_array_start;
380 | [_stream skip];
381 | break;
382 |
383 | case ']':
384 | tok = sbjson_token_array_end;
385 | [_stream skip];
386 | break;
387 |
388 | case '{':
389 | tok = sbjson_token_object_start;
390 | [_stream skip];
391 | break;
392 |
393 | case ':':
394 | tok = sbjson_token_keyval_separator;
395 | [_stream skip];
396 | break;
397 |
398 | case '}':
399 | tok = sbjson_token_object_end;
400 | [_stream skip];
401 | break;
402 |
403 | case ',':
404 | tok = sbjson_token_separator;
405 | [_stream skip];
406 | break;
407 |
408 | case 'n':
409 | tok = [self match:"null" length:4 retval:sbjson_token_null];
410 | break;
411 |
412 | case 't':
413 | tok = [self match:"true" length:4 retval:sbjson_token_true];
414 | break;
415 |
416 | case 'f':
417 | tok = [self match:"false" length:5 retval:sbjson_token_false];
418 | break;
419 |
420 | case '"':
421 | tok = [self getStringToken:token];
422 | break;
423 |
424 | case '0' ... '9':
425 | case '-':
426 | tok = [self getNumberToken:token];
427 | break;
428 |
429 | case '+':
430 | self.error = @"Leading + is illegal in number";
431 | tok = sbjson_token_error;
432 | break;
433 |
434 | default:
435 | self.error = [NSString stringWithFormat:@"Illegal start of token [%c]", ch];
436 | tok = sbjson_token_error;
437 | break;
438 | }
439 |
440 | if (tok == sbjson_token_eof) {
441 | // We ran out of bytes in the middle of a token.
442 | // We don't know how to restart in mid-flight, so
443 | // rewind to the start of the token for next attempt.
444 | // Hopefully we'll have more data then.
445 | _stream.index = oldIndexLocation;
446 | }
447 |
448 | return tok;
449 | }
450 |
451 |
452 | @end
453 |
--------------------------------------------------------------------------------
/PSGoogleReader/SBJSON/SBJsonUTF8Stream.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2011, 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
6 | met:
7 |
8 | Redistributions of source code must retain the above copyright
9 | notice, this list of conditions and the following disclaimer.
10 |
11 | Redistributions in binary form must reproduce the above copyright
12 | notice, this list of conditions and the following disclaimer in the
13 | documentation and/or other materials provided with the distribution.
14 |
15 | Neither the name of the the author nor the names of its contributors
16 | may be used to endorse or promote products derived from this software
17 | without specific prior written permission.
18 |
19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
20 | IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
22 | PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 | HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 | */
31 |
32 | #import
33 |
34 |
35 | @interface SBJsonUTF8Stream : NSObject {
36 | @private
37 | const char *_bytes;
38 | NSMutableData *_data;
39 | NSUInteger _length;
40 | }
41 |
42 | @property (assign) NSUInteger index;
43 |
44 | - (void)appendData:(NSData*)data_;
45 |
46 | - (BOOL)haveRemainingCharacters:(NSUInteger)chars;
47 |
48 | - (void)skip;
49 | - (void)skipWhitespace;
50 | - (BOOL)skipCharacters:(const char *)chars length:(NSUInteger)len;
51 |
52 | - (BOOL)getUnichar:(unichar*)ch;
53 | - (BOOL)getNextUnichar:(unichar*)ch;
54 | - (BOOL)getSimpleString:(NSString**)string;
55 |
56 | - (NSString*)stringWithRange:(NSRange)range;
57 |
58 | @end
59 |
--------------------------------------------------------------------------------
/PSGoogleReader/SBJSON/SBJsonUTF8Stream.m:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2011, 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
6 | met:
7 |
8 | Redistributions of source code must retain the above copyright
9 | notice, this list of conditions and the following disclaimer.
10 |
11 | Redistributions in binary form must reproduce the above copyright
12 | notice, this list of conditions and the following disclaimer in the
13 | documentation and/or other materials provided with the distribution.
14 |
15 | Neither the name of the the author nor the names of its contributors
16 | may be used to endorse or promote products derived from this software
17 | without specific prior written permission.
18 |
19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
20 | IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
22 | PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 | HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 | */
31 |
32 | #import "SBJsonUTF8Stream.h"
33 |
34 |
35 | @implementation SBJsonUTF8Stream
36 |
37 | @synthesize index = _index;
38 |
39 | - (id)init {
40 | self = [super init];
41 | if (self) {
42 | _data = [[NSMutableData alloc] initWithCapacity:4096u];
43 | }
44 | return self;
45 | }
46 |
47 |
48 | - (void)appendData:(NSData *)data_ {
49 |
50 | if (_index) {
51 | // Discard data we've already parsed
52 | [_data replaceBytesInRange:NSMakeRange(0, _index) withBytes:"" length:0];
53 |
54 | // Reset index to point to current position
55 | _index = 0;
56 | }
57 |
58 | [_data appendData:data_];
59 |
60 | // This is an optimisation.
61 | _bytes = [_data bytes];
62 | _length = [_data length];
63 | }
64 |
65 |
66 | - (BOOL)getUnichar:(unichar*)ch {
67 | if (_index < _length) {
68 | *ch = (unichar)_bytes[_index];
69 | return YES;
70 | }
71 | return NO;
72 | }
73 |
74 | - (BOOL)getNextUnichar:(unichar*)ch {
75 | if (++_index < _length) {
76 | *ch = (unichar)_bytes[_index];
77 | return YES;
78 | }
79 | return NO;
80 | }
81 |
82 | - (BOOL)getSimpleString:(NSString **)string {
83 | NSUInteger start = _index;
84 | while (_index < _length) {
85 | switch (_bytes[_index]) {
86 | case '"':
87 | case '\\':
88 | case 0 ... 0x1f:
89 | *string = [[NSString alloc] initWithBytes:(_bytes + start) length:(_index - start) encoding:NSUTF8StringEncoding];
90 | return YES;
91 | break;
92 | default:
93 | _index++;
94 | break;
95 | }
96 | }
97 | return NO;
98 | }
99 |
100 | - (void)skip {
101 | _index++;
102 | }
103 |
104 | - (void)skipWhitespace {
105 | while (_index < _length) {
106 | switch (_bytes[_index]) {
107 | case ' ':
108 | case '\t':
109 | case '\r':
110 | case '\n':
111 | _index++;
112 | break;
113 | default:
114 | return;
115 | break;
116 | }
117 | }
118 | }
119 |
120 | - (BOOL)haveRemainingCharacters:(NSUInteger)chars {
121 | return [_data length] - _index >= chars;
122 | }
123 |
124 | - (BOOL)skipCharacters:(const char *)chars length:(NSUInteger)len {
125 | const void *bytes = [_data bytes] + _index;
126 | if (!memcmp(bytes, chars, len)) {
127 | _index += len;
128 | return YES;
129 | }
130 | return NO;
131 | }
132 |
133 | - (NSString*)stringWithRange:(NSRange)range {
134 | return [[NSString alloc] initWithBytes:_bytes + range.location length:range.length encoding:NSUTF8StringEncoding];
135 |
136 | }
137 |
138 |
139 | @end
140 |
--------------------------------------------------------------------------------
/PSGoogleReader/SBJSON/SBJsonWriter.h:
--------------------------------------------------------------------------------
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
31 |
32 | /**
33 | @brief The JSON writer class.
34 |
35 | This uses SBJsonStreamWriter internally.
36 |
37 | @see @ref json2objc
38 | */
39 |
40 | @interface SBJsonWriter : NSObject
41 |
42 | /**
43 | @brief The maximum recursing depth.
44 |
45 | Defaults to 32. If the input is nested deeper than this the input will be deemed to be
46 | malicious and the parser returns nil, signalling an error. ("Nested too deep".) You can
47 | turn off this security feature by setting the maxDepth value to 0.
48 | */
49 | @property NSUInteger maxDepth;
50 |
51 | /**
52 | @brief Return an error trace, or nil if there was no errors.
53 |
54 | Note that this method returns the trace of the last method that failed.
55 | You need to check the return value of the call you're making to figure out
56 | if the call actually failed, before you know call this method.
57 | */
58 | @property (readonly, copy) NSString *error;
59 |
60 | /**
61 | @brief Whether we are generating human-readable (multiline) JSON.
62 |
63 | Set whether or not to generate human-readable JSON. The default is NO, which produces
64 | JSON without any whitespace. (Except inside strings.) If set to YES, generates human-readable
65 | JSON with linebreaks after each array value and dictionary key/value pair, indented two
66 | spaces per nesting level.
67 | */
68 | @property BOOL humanReadable;
69 |
70 | /**
71 | @brief Whether or not to sort the dictionary keys in the output.
72 |
73 | If this is set to YES, the dictionary keys in the JSON output will be in sorted order.
74 | (This is useful if you need to compare two structures, for example.) The default is NO.
75 | */
76 | @property BOOL sortKeys;
77 |
78 | /**
79 | @brief Return JSON representation for the given object.
80 |
81 | Returns a string containing JSON representation of the passed in value, or nil on error.
82 | If nil is returned and @p error is not NULL, @p *error can be interrogated to find the cause of the error.
83 |
84 | @param value any instance that can be represented as JSON text.
85 | */
86 | - (NSString*)stringWithObject:(id)value;
87 |
88 | /**
89 | @brief Return JSON representation for the given object.
90 |
91 | Returns an NSData object containing JSON represented as UTF8 text, or nil on error.
92 |
93 | @param value any instance that can be represented as JSON text.
94 | */
95 | - (NSData*)dataWithObject:(id)value;
96 |
97 | /**
98 | @brief Return JSON representation (or fragment) for the given object.
99 |
100 | Returns a string containing JSON representation of the passed in value, or nil on error.
101 | If nil is returned and @p error is not NULL, @p *error can be interrogated to find the cause of the error.
102 |
103 | @param value any instance that can be represented as a JSON fragment
104 | @param error pointer to object to be populated with NSError on failure
105 |
106 | */- (NSString*)stringWithObject:(id)value
107 | error:(NSError**)error;
108 |
109 |
110 | @end
111 |
--------------------------------------------------------------------------------
/PSGoogleReader/SBJSON/SBJsonWriter.m:
--------------------------------------------------------------------------------
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 | #import "SBJsonStreamWriter.h"
32 | #import "SBJsonStreamWriterAccumulator.h"
33 |
34 |
35 | @interface SBJsonWriter ()
36 | @property (copy) NSString *error;
37 | @end
38 |
39 | @implementation SBJsonWriter
40 |
41 | @synthesize sortKeys;
42 | @synthesize humanReadable;
43 |
44 | @synthesize error;
45 | @synthesize maxDepth;
46 |
47 | - (id)init {
48 | self = [super init];
49 | if (self) {
50 | self.maxDepth = 32u;
51 | }
52 | return self;
53 | }
54 |
55 |
56 | - (NSString*)stringWithObject:(id)value {
57 | NSData *data = [self dataWithObject:value];
58 | if (data)
59 | return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
60 | return nil;
61 | }
62 |
63 | - (NSString*)stringWithObject:(id)value error:(NSError**)error_ {
64 | NSString *tmp = [self stringWithObject:value];
65 | if (tmp)
66 | return tmp;
67 |
68 | if (error_) {
69 | NSDictionary *ui = [NSDictionary dictionaryWithObjectsAndKeys:error, NSLocalizedDescriptionKey, nil];
70 | *error_ = [NSError errorWithDomain:@"org.brautaset.SBJsonWriter.ErrorDomain" code:0 userInfo:ui];
71 | }
72 |
73 | return nil;
74 | }
75 |
76 | - (NSData*)dataWithObject:(id)object {
77 | self.error = nil;
78 |
79 | SBJsonStreamWriterAccumulator *accumulator = [[SBJsonStreamWriterAccumulator alloc] init];
80 |
81 | SBJsonStreamWriter *streamWriter = [[SBJsonStreamWriter alloc] init];
82 | streamWriter.sortKeys = self.sortKeys;
83 | streamWriter.maxDepth = self.maxDepth;
84 | streamWriter.humanReadable = self.humanReadable;
85 | streamWriter.delegate = accumulator;
86 |
87 | BOOL ok = NO;
88 | if ([object isKindOfClass:[NSDictionary class]])
89 | ok = [streamWriter writeObject:object];
90 |
91 | else if ([object isKindOfClass:[NSArray class]])
92 | ok = [streamWriter writeArray:object];
93 |
94 | else if ([object respondsToSelector:@selector(proxyForJson)])
95 | return [self dataWithObject:[object proxyForJson]];
96 | else {
97 | self.error = @"Not valid type for JSON";
98 | return nil;
99 | }
100 |
101 | if (ok)
102 | return accumulator.data;
103 |
104 | self.error = streamWriter.error;
105 | return nil;
106 | }
107 |
108 |
109 | @end
110 |
--------------------------------------------------------------------------------
/PSGoogleReader/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /* Localized versions of Info.plist keys */
2 |
3 |
--------------------------------------------------------------------------------
/PSGoogleReader/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // PSGoogleReader
4 | //
5 | // Created by Daniel Isenhower ( daniel@perspecdev.com ) on 5/24/11.
6 | // Copyright 2011 PerspecDev Solutions, LLC. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | #import "PSGoogleReaderAppDelegate.h"
12 |
13 | int main(int argc, char *argv[])
14 | {
15 | @autoreleasepool {
16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([PSGoogleReaderAppDelegate class]));
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/README:
--------------------------------------------------------------------------------
1 | PSGoogleReader is a class that connects to Google Reader. I don't have a pretty
2 | demo UI set up, so you won't see much in the simulator when you run this app. Check
3 | NSLog output to see very simplified demo results.
4 |
5 | Be sure to set your client (app) name in PSGoogleReader.m
6 | Set your Google Reader username/password in PSGoogleReaderAppDelegate.m
7 |
8 | Code license is pretty generous. See comments at the top of PSGoogleReader.m for details.
9 |
10 | Email me if you have any questions: daniel@perspecdev.com
--------------------------------------------------------------------------------