Skip to content
Browse files

Updating libraries and including nextive parser

  • Loading branch information...
1 parent 2ad268f commit e0d9c5ba5dd77340e8e333de929a73b649f81dad @gabriel committed
Showing with 7,286 additions and 3,157 deletions.
  1. +1 −1 Classes/JSONTest.h
  2. +16 −3 Classes/JSONTest.m
  3. +0 −160 Frameworks/JSONKit-1.4/CHANGELOG.md
  4. +0 −166 Frameworks/JSONKit-1.4/JSONKit.h
  5. +0 −210 Frameworks/JSONKit-1.4/README.md
  6. +251 −0 Frameworks/JSONKit-20110725/JSONKit.h
  7. +1,111 −446 Frameworks/{JSONKit-1.4 → JSONKit-20110725}/JSONKit.m
  8. +41 −0 Frameworks/NextiveJson-20110725/NSError+Extensions.h
  9. +44 −0 Frameworks/NextiveJson-20110725/NSError+Extensions.m
  10. +124 −0 Frameworks/NextiveJson-20110725/NXDebug.h
  11. +131 −0 Frameworks/NextiveJson-20110725/NXDebug.m
  12. +106 −0 Frameworks/NextiveJson-20110725/NXJsonParser.h
  13. +873 −0 Frameworks/NextiveJson-20110725/NXJsonParser.m
  14. +83 −0 Frameworks/NextiveJson-20110725/NXJsonSerializer.h
  15. +704 −0 Frameworks/NextiveJson-20110725/NXJsonSerializer.m
  16. +37 −0 Frameworks/NextiveJson-20110725/NXSerializable.h
  17. +0 −68 Frameworks/SBJSON-2.2.2/NSObject+SBJSON.h
  18. +0 −75 Frameworks/SBJSON-2.2.2/SBJSON.h
  19. +0 −212 Frameworks/SBJSON-2.2.2/SBJSON.m
  20. +0 −78 Frameworks/SBJSON-2.2.2/SBJsonBase.m
  21. +0 −87 Frameworks/SBJSON-2.2.2/SBJsonParser.h
  22. +0 −475 Frameworks/SBJSON-2.2.2/SBJsonParser.m
  23. +0 −228 Frameworks/SBJSON-2.2.2/SBJsonWriter.m
  24. +23 −14 Frameworks/{SBJSON-2.2.2/NSString+SBJSON.h → SBJSON-3.0.1/NSObject+SBJson.h}
  25. +19 −14 Frameworks/{SBJSON-2.2.2/NSObject+SBJSON.m → SBJSON-3.0.1/NSObject+SBJson.m}
  26. +84 −0 Frameworks/SBJSON-3.0.1/SBJson.h
  27. +58 −37 Frameworks/{SBJSON-2.2.2/SBJsonBase.h → SBJSON-3.0.1/SBJsonParser.h}
  28. +104 −0 Frameworks/SBJSON-3.0.1/SBJsonParser.m
  29. +167 −0 Frameworks/SBJSON-3.0.1/SBJsonStreamParser.h
  30. +246 −0 Frameworks/SBJSON-3.0.1/SBJsonStreamParser.m
  31. +40 −0 Frameworks/SBJSON-3.0.1/SBJsonStreamParserAccumulator.h
  32. +16 −20 Frameworks/{SBJSON-2.2.2/NSString+SBJSON.m → SBJSON-3.0.1/SBJsonStreamParserAccumulator.m}
  33. +148 −0 Frameworks/SBJSON-3.0.1/SBJsonStreamParserAdapter.h
  34. +171 −0 Frameworks/SBJSON-3.0.1/SBJsonStreamParserAdapter.m
  35. +81 −0 Frameworks/SBJSON-3.0.1/SBJsonStreamParserState.h
  36. +347 −0 Frameworks/SBJSON-3.0.1/SBJsonStreamParserState.m
  37. +194 −0 Frameworks/SBJSON-3.0.1/SBJsonStreamWriter.h
  38. +375 −0 Frameworks/SBJSON-3.0.1/SBJsonStreamWriter.m
  39. +39 −0 Frameworks/SBJSON-3.0.1/SBJsonStreamWriterAccumulator.h
  40. +24 −18 Frameworks/{SBJSON-2.2.2/JSON.h → SBJSON-3.0.1/SBJsonStreamWriterAccumulator.m}
  41. +69 −0 Frameworks/SBJSON-3.0.1/SBJsonStreamWriterState.h
  42. +139 −0 Frameworks/SBJSON-3.0.1/SBJsonStreamWriterState.m
  43. +70 −0 Frameworks/SBJSON-3.0.1/SBJsonTokeniser.h
  44. +454 −0 Frameworks/SBJSON-3.0.1/SBJsonTokeniser.m
  45. +59 −0 Frameworks/SBJSON-3.0.1/SBJsonUTF8Stream.h
  46. +143 −0 Frameworks/SBJSON-3.0.1/SBJsonUTF8Stream.m
  47. +45 −59 Frameworks/{SBJSON-2.2.2 → SBJSON-3.0.1}/SBJsonWriter.h
  48. +113 −0 Frameworks/SBJSON-3.0.1/SBJsonWriter.m
  49. +6 −3 Frameworks/TouchJSON/CDataScanner.h
  50. +255 −187 Frameworks/TouchJSON/CDataScanner.m
  51. +3 −0 Frameworks/TouchJSON/Extensions/CDataScanner_Extensions.h
  52. +71 −16 Frameworks/TouchJSON/Extensions/CDataScanner_Extensions.m
  53. +0 −36 Frameworks/TouchJSON/Extensions/NSCharacterSet_Extensions.h
  54. +0 −48 Frameworks/TouchJSON/Extensions/NSCharacterSet_Extensions.m
  55. +1 −0 Frameworks/TouchJSON/Extensions/NSDictionary_JSONExtensions.h
  56. +9 −3 Frameworks/TouchJSON/Extensions/NSDictionary_JSONExtensions.m
  57. +0 −44 Frameworks/TouchJSON/Extensions/NSScanner_Extensions.h
  58. +0 −118 Frameworks/TouchJSON/Extensions/NSScanner_Extensions.m
  59. +0 −46 Frameworks/TouchJSON/JSON/CJSONDataSerializer.h
  60. +0 −229 Frameworks/TouchJSON/JSON/CJSONDataSerializer.m
  61. +20 −2 Frameworks/TouchJSON/JSON/CJSONDeserializer.h
  62. +119 −53 Frameworks/TouchJSON/JSON/CJSONDeserializer.m
  63. +52 −1 Frameworks/TouchJSON/JSON/CJSONScanner.h
Sorry, we could not display the entire diff because it was too big.
View
2 Classes/JSONTest.h
@@ -22,7 +22,7 @@ do { \
CFAbsoluteTime start = CFAbsoluteTimeGetCurrent(); \
for(NSInteger i = 0; i < count; i++) { \
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; \
- id value = (expr); value; \
+ expr; \
[pool release]; \
} \
\
View
19 Classes/JSONTest.m
@@ -9,9 +9,10 @@
#import "JSONTest.h"
#import <YAJLiOS/YAJL.h>
-#import "NSString+SBJSON.h"
+#import "SBJson.h"
#import "CJSONDeserializer.h"
#import "JSONKit.h"
+#import "NXJsonParser.h"
@implementation JSONTest
@@ -52,9 +53,20 @@ - (void)touchJSONTest:(NSString *)resourceName count:(NSInteger)count {
- (void)JSONKitTest:(NSString *)resourceName count:(NSInteger)count {
NSData *JSONData = [[self loadDataFromResource:resourceName] retain];
- RunWithCount(count, ([NSString stringWithFormat:@"JSONKit-%@", resourceName]), { [JSONData objectFromJSONData]; });
+ RunWithCount(count, ([NSString stringWithFormat:@"JSONKit-%@", resourceName]), {
+ [JSONData objectFromJSONData];
+ });
+ [JSONData release];
+}
+
+- (void)nextiveJsonTest:(NSString *)resourceName count:(NSInteger)count {
+ NSData *JSONData = [[self loadDataFromResource:resourceName] retain];
+ RunWithCount(count, ([NSString stringWithFormat:@"NextiveJson-%@", resourceName]), {
+ NXJsonParser *parser = [[NXJsonParser alloc] initWithData:JSONData];
+ id value = [parser parse:nil ignoreNulls:NO]; value;
+ [parser release];
+ });
[JSONData release];
-
}
- (void)runWithResourceName:(NSString *)resourceName count:(NSInteger)count {
@@ -62,6 +74,7 @@ - (void)runWithResourceName:(NSString *)resourceName count:(NSInteger)count {
[self YAJLTest:resourceName count:count];
[self touchJSONTest:resourceName count:count];
[self JSONKitTest:resourceName count:count];
+ [self nextiveJsonTest:resourceName count:count];
}
@end
View
160 Frameworks/JSONKit-1.4/CHANGELOG.md
@@ -1,160 +0,0 @@
-# JSONKit Changelog
-
-## Version 1.4 2011/28/02
-
-### Bug Fixes
-
-* JSONKit has a fast and a slow path for parsing JSON Strings. The slow path is needed whenever special string processing is required, such as the conversion of `\` escape sequences or ill-formed UTF-8. Although the slow path had a check for characters < `0x20`, which are not permitted by the [RFC 4627][], there was a bug such that the condition was never actually checked. As a result, JSONKit would have incorrectly accepted JSON that contained characters < `0x20` if it was using the slow path to process a JSON String.
-* The low surrogate in a <code>\u<i><b>high</b></i>\u<i><b>low</b></i></code> escape sequence in a JSON String was incorrectly treating `dfff` as ill-formed Unicode. This was due to a comparison that used `>= 0xdfff` instead of `> 0xdfff` as it should have.
-* `JKParseOptionLooseUnicode` was not properly honored when parsing some types of ill-formed Unicode in <code>\u<i><b>HHHH</b></i></code> escapes in JSON Strings.
-
-### Important Changes
-
-* The `JK_ENABLE_CF_TRANSFER_OWNERSHIP_CALLBACKS` pre-processor define flag that was added to JSONKit v1.3 has been removed.
-
- `JK_ENABLE_CF_TRANSFER_OWNERSHIP_CALLBACKS` was added in JSONKit v1.3 as a temporary work around. While the author was aware of other ways to fix the particular problem caused by the usage of "transfer of ownership callbacks" with Core Foundation classes, the fix provided in JSONKit v1.3 was trivial to implement. This allowed people who needed that functionality to use JSONKit while a proper solution to the problem was worked on. JSONKit v1.4 is the result of that work.
-
- JSONKit v1.4 no longer uses the Core Foundation collection classes [`CFArray`][CFArray] and [`CFDictionary`][CFDictionary]. Instead, JSONKit v1.4 contains a concrete subclass of [`NSArray`][NSArray] and [`NSDictionary`][NSDictionary]&ndash; `JKArray` and `JKDictionary`, respectively. As a result, JSONKit has complete control over the behavior of how items are added and managed within an instantiated collection object. The `JKArray` and `JKDictionary` classes are private to JSONKit, you should not instantiate them direction. Since they are concrete subclasses of their respective collection class cluster, they behave and act exactly the same as [`NSArray`][NSArray] and [`NSDictionary`][NSDictionary].
-
- The first benefit is that the "transfer of ownership" object ownership policy can now be safely used. Because the JSONKit collection objects understand that some methods, such as [`-mutableCopy`][-mutableCopy], should not inherit the same "transfer of ownership" object ownership policy, but must follow the standard Cocoa object ownership policy. The "transfer of ownership" object ownership policy reduces the number of [`-retain`][-retain] and [`-release`][-release] calls needed to add an object to a collection, and when creating a large number of objects very quickly (as you would expect when parsing JSON), this can result in a non-trivial amount of time. Eliminating these calls means faster JSON parsing.
-
- A second benefit is that the author encountered some unexpected behavior when using the [`CFDictionaryCreate`][CFDictionaryCreate] function to create a dictionary and the `keys` argument contained duplicate keys. This required JSONKit to de-duplicate the keys and values before calling [`CFDictionaryCreate`][CFDictionaryCreate]. Unfortunately, JSONKit always had to scan all the keys to make sure there were no duplicates, even though 99.99% of the time there were none. This was less than optimal, particularly because one of the solutions to this particular problem is to use a hash table to perform the de-duplication. Now JSONKit can do the de-duplication while it is instantiating the dictionary collection, solving two problems at once.
-
- Yet another benefit is that the recently instantiated object cache that JSONKit uses can be used to cache information about the keys used to create dictionary collections, in particular a keys [`-hash`][-hash] value. For a lot of real world JSON, this effectively means that the [`-hash`][-hash] for a key is calculated once, and that value is reused again and again when creating dictionaries. Because all the information required to create the hash table used by `JKDictionary` is already determined at the time the `JKDictionary` object is instantiated, populating the `JKDictionary` is now a very tight loop that only has to call [`-isEqual:`][-isEqual:] on the rare occasions that the JSON being parsed contains duplicate keys. Since the functions that handle this logic are all declared `static` and are internal to JSONKit, the compiler can heavily optimize this code.
-
- What does this mean in terms of performance? JSONKit was already fast, but now, it's even faster. Below is some benchmark times for [`twitter_public_timeline.json`][twitter_public_timeline.json] in [samsoffes / json-benchmarks](https://github.com/samsoffes/json-benchmarks), where _read_ means to convert the JSON to native Objective-C objects, and _write_ means to convert the native Objective-C to JSON&mdash;
-
- <pre>
- v1.3 read : min: 456.000 us, avg: 460.056 us, char/s: 53341332.36 / 50.870 MB/s
- v1.3 write: min: 150.000 us, avg: 151.816 us, char/s: 161643041.58 / 154.155 MB/s</pre>
-
- <pre>
- v1.4 read : min: 285.000 us, avg: 288.603 us, char/s: 85030301.14 / 81.091 MB/s
- v1.4 write: min: 127.000 us, avg: 129.617 us, char/s: 189327017.29 / 180.556 MB/s</pre>
-
- JSONKit v1.4 is nearly 60% faster at reading and 17% faster at writing than v1.3.
-
- The following is the JSON test file taken from the project available at [this blog post](http://psionides.jogger.pl/2010/12/12/cocoa-json-parsing-libraries-part-2/). The keys and information contained in the JSON was anonymized with random characters. Since JSONKit relies on its recently instantiated object cache for a lot of its performance, this JSON happens to be "the worst corner case possible".
-
- <pre>
- v1.3 read : min: 5222.000 us, avg: 5262.344 us, char/s: 15585260.10 / 14.863 MB/s
- v1.3 write: min: 1253.000 us, avg: 1259.914 us, char/s: 65095712.88 / 62.080 MB/s</pre>
-
- <pre>
- v1.4 read : min: 4096.000 us, avg: 4122.240 us, char/s: 19895736.30 / 18.974 MB/s
- v1.4 write: min: 1319.000 us, avg: 1335.538 us, char/s: 61409709.05 / 58.565 MB/s</pre>
-
- JSONKit v1.4 is 28% faster at reading and 6% faster at writing that v1.3 in this worst-case torture test.
-
- While your milage may vary, you will likely see improvements in the 50% for reading and 10% for writing on your real world JSON. The nature of JSONKits cache means performance improvements is statistical in nature and depends on the particular properties of the JSON being parsed.
-
- For comparison, [json-framework][], a popular Objective-C JSON parsing library, turns in the following benchmark times for [`twitter_public_timeline.json`][twitter_public_timeline.json]&mdash;
-
- <pre>
- read : min: 1670.000 us, avg: 1682.461 us, char/s: 14585776.43 / 13.910 MB/s
- write: min: 1021.000 us, avg: 1028.970 us, char/s: 23849091.81 / 22.744 MB/s</pre>
-
- Since the benchmark for JSONKit and [json-framework][] was done on the same computer, it's safe to compare the timing results. The version of [json-framework][] used was the latest v3.0 available via the master branch at the time of this writing on github.com.
-
- JSONKit v1.4 is 483% faster at reading and 694% faster at writing than [json-framework][].
-
-### Important Notes
-
-* JSONKit v1.4 now uses custom concrete subclasses of [`NSArray`][NSArray] and [`NSDictionary`][NSDictionary].
-
- In theory, these custom classes should behave exactly the same as the respective Foundation / Cocoa counterparts.
-
- As usual, in practice may have non-linear excursions from what theory predicts. It is also virtually impossible to properly test or predict how these custom classes will interact with software in the wild.
-
- Most likely, if you do encounter a problem, it will happen very quickly, and you should report a bug via the [github.com JSONKit Issue Tracker][bugtracker].
-
-
-### Other Changes
-
-* Added a `__clang_analyzer__` pre-processor conditional around some code that the `clang` static analyzer was giving false positives for. However, `clang` versions &le; 1.5 do not define `__clang_analyzer__` and therefore will continue to emit analyzer warnings.
-* The cache now uses a linear congruential generator to select which item in the cache to randomly age. This should age items in the cache more fairly.
-* Removed a lot of internal and private data structures from `JSONKit.h` and put them in `JSONKit.m`.
-* Modified the way floating point values are serialized. Previously, the [`printf`][printf] format conversion `%.16g` was used. This was changed to `%.17g` which should theoretically allow for up to a full `float`, or [IEEE 754 Single 32-bit floating-point][Single Precision], of precision when converting floating point values to decimal representation.
-* The usual sundry of inconsequential tidies and what not, such as updating the README.md, etc.
-
-## Version 1.3 2011/05/02
-
-### New Features
-
-* Added the `JK_ENABLE_CF_TRANSFER_OWNERSHIP_CALLBACKS` pre-processor define flag.
-
- This is typically enabled by adding <span style="white-space: nowrap;">`-DJK_ENABLE_CF_TRANSFER_OWNERSHIP_CALLBACKS`</span> to the compilers command line arguments or in `Xcode.app` by adding `JK_ENABLE_CF_TRANSFER_OWNERSHIP_CALLBACKS` to a projects / targets `Pre-Processor Macros` settings.
-
- The `JK_ENABLE_CF_TRANSFER_OWNERSHIP_CALLBACKS` option enables the use of custom Core Foundation collection call backs which omit the [`CFRetain`][CFRetain] calls. This results in saving several [`CFRetain`][CFRetain] and [`CFRelease`][CFRelease] calls typically needed for every single object from the parsed JSON. While the author has used this technique for years without any issues, an unexpected interaction with the Foundation [`-mutableCopy`][-mutableCopy] method and Core Foundation Toll-Free Bridging resulting in a condition in which the objects contained in the collection to be over released. This problem does not occur with the use of [`-copy`][-copy] due to the fact that the objects created by JSONKit are immutable, and therefore [`-copy`][-copy] does not require creating a completely new object and copying the contents, instead [`-copy`][-copy] simply returns a [`-retain`][-retain]'d version of the immutable object which is significantly faster along with the obvious reduction in memory usage.
-
- Prior to version 1.3, JSONKit always used custom "Transfer of Ownership Collection Callbacks", and thus `JK_ENABLE_CF_TRANSFER_OWNERSHIP_CALLBACKS` was effectively implicitly defined.
-
- Beginning with version 1.3, the default behavior of JSONKit is to use the standard Core Foundation collection callbacks ([`kCFTypeArrayCallBacks`][kCFTypeArrayCallBacks], [`kCFTypeDictionaryKeyCallBacks`][kCFTypeDictionaryKeyCallBacks], and [`kCFTypeDictionaryValueCallBacks`][kCFTypeDictionaryValueCallBacks]). The intention is to follow "the principle of least surprise", and the author believes the use of the standard Core Foundation collection callbacks as the default behavior for JSONKit results in the least surprise.
-
- **NOTE**: `JK_ENABLE_CF_TRANSFER_OWNERSHIP_CALLBACKS` is only applicable to `(CF|NS)` `Dictionary` and `Array` class objects.
-
- For the vast majority of users, the author believes JSONKits custom "Transfer of Ownership Collection Callbacks" will not cause any problems. As previously stated, the author has used this technique in performance critical code for years and has never had a problem. Until a user reported a problem with [`-mutableCopy`][-mutableCopy], the author was unaware that the use of the custom callbacks could even cause a problem. This is probably due to the fact that the vast majority of time the typical usage pattern tends to be "iterate the contents of the collection" and very rarely mutate the returned collection directly (although this last part is likely to vary significantly from programmer to programmer). The author tends to avoid the use of [`-mutableCopy`][-mutableCopy] as it results in a significant performance and memory consumption penalty. The reason for this is in "typical" Cocoa coding patterns, using [`-mutableCopy`][-mutableCopy] will instantiate an identical, albeit mutable, version of the original object. This requires both memory for the new object and time to iterate the contents of the original object and add them to the new object. Furthermore, under "typical" Cocoa coding patterns, the original collection object continues to consume memory until the autorelease pool is released. However, clearly there are cases where the use of [`-mutableCopy`][-mutableCopy] makes sense or may be used by an external library which is out of your direct control.
-
- The use of the standard Core Foundation collection callbacks results in a 9% to 23% reduction in parsing performance, with an "eye-balled average" of around 13% according to some benchmarking done by the author using Real World&trade; JSON (i.e., actual JSON from various web services, such as Twitter, etc) using `gcc-4.2 -arch x86_64 -O3 -DNS_BLOCK_ASSERTIONS` with the only change being the addition of <span style="white-space: nowrap;">`-DJK_ENABLE_CF_TRANSFER_OWNERSHIP_CALLBACKS`</span>.
-
- `JK_ENABLE_CF_TRANSFER_OWNERSHIP_CALLBACKS` is only applicable to parsing / deserializing (i.e. converting from) of JSON. Serializing (i.e., converting to JSON) is completely unaffected by this change.
-
-### Bug Fixes
-
-* Fixed a [bug report regarding `-mutableCopy`](https://github.com/johnezang/JSONKit/issues#issue/3). This is related to the addition of the pre-processor define flag `JK_ENABLE_CF_TRANSFER_OWNERSHIP_CALLBACKS`.
-
-### Other Changes
-
-* Added `JK_EXPECTED` optimization hints around several conditionals.
-* When serializing objects, JSONKit first starts with a small, on stack buffer. If the encoded JSON exceeds the size of the stack buffer, JSONKit switches to a heap allocated buffer. If JSONKit switched to a heap allocated buffer, [`CFDataCreateWithBytesNoCopy`][CFDataCreateWithBytesNoCopy] is used to create the [`NSData`][NSData] object, which in most cases causes the heap allocated buffer to "transfer" to the [`NSData`][NSData] object which is substantially faster than allocating a new buffer and copying the bytes.
-* Added a pre-processor check in `JSONKit.m` to see if Objective-C Garbage Collection is enabled and issue a `#error` notice that JSONKit does not support Objective-C Garbage Collection.
-* Various other minor or trivial modifications, such as updating `README.md`.
-
-### Other Issues
-
-* When using the `clang` static analyzer (the version used at the time of this writing was `Apple clang version 1.5 (tags/Apple/clang-60)`), the static analyzer reports a number of problems with `JSONKit.m`.
-
- The author has investigated these issues and determined that the problems reported by the current version of the static analyzer are "false positives". Not only that, the reported problems are not only "false positives", they are very clearly and obviously wrong. Therefore, the author has made the decision that no action will be taken on these non-problems, which includes not modifying the code for the sole purpose of silencing the static analyzer. The justification for this is "the dog wags the tail, not the other way around."
-
-## Version 1.2 2011/01/08
-
-### Bug Fixes
-
-* When JSONKit attempted to parse and decode JSON that contained `{"key": value}` dictionaries that contained the same key more than once would likely result in a crash. This was a serious bug.
-* Under some conditions, JSONKit could potentially leak memory.
-* There was an off by one error in the code that checked whether or not the parser was at the end of the `UTF8` buffer. This could result in JSONKit reading one by past the buffer bounds in some cases.
-
-### Other Changes
-
-* Some of the methods were missing `NULL` pointer checks for some of their arguments. This was fixed. In generally, when JSONKit encounters invalid arguments, it throws a `NSInvalidArgumentException` exception.
-* Various other minor changes such as tightening up numeric literals with `UL` or `L` qualification, assertion check tweaks and additions, etc.
-* The README.md file was updated with additional information.
-
-### Version 1.1
-
-No change log information was kept for versions prior to 1.2.
-
-[bugtracker]: https://github.com/johnezang/JSONKit/issues
-[RFC 4627]: http://tools.ietf.org/html/rfc4627
-[twitter_public_timeline.json]: https://github.com/samsoffes/json-benchmarks/blob/master/Resources/twitter_public_timeline.json
-[json-framework]: https://github.com/stig/json-framework
-[Single Precision]: http://en.wikipedia.org/wiki/Single_precision
-[kCFTypeArrayCallBacks]: http://developer.apple.com/library/mac/documentation/CoreFoundation/Reference/CFArrayRef/Reference/reference.html#//apple_ref/c/data/kCFTypeArrayCallBacks
-[kCFTypeDictionaryKeyCallBacks]: http://developer.apple.com/library/mac/documentation/CoreFoundation/Reference/CFDictionaryRef/Reference/reference.html#//apple_ref/c/data/kCFTypeDictionaryKeyCallBacks
-[kCFTypeDictionaryValueCallBacks]: http://developer.apple.com/library/mac/documentation/CoreFoundation/Reference/CFDictionaryRef/Reference/reference.html#//apple_ref/c/data/kCFTypeDictionaryValueCallBacks
-[CFRetain]: http://developer.apple.com/library/mac/documentation/CoreFoundation/Reference/CFTypeRef/Reference/reference.html#//apple_ref/c/func/CFRetain
-[CFRelease]: http://developer.apple.com/library/mac/documentation/CoreFoundation/Reference/CFTypeRef/Reference/reference.html#//apple_ref/c/func/CFRelease
-[CFDataCreateWithBytesNoCopy]: http://developer.apple.com/library/mac/documentation/CoreFoundation/Reference/CFDataRef/Reference/reference.html#//apple_ref/c/func/CFDataCreateWithBytesNoCopy
-[CFArray]: http://developer.apple.com/library/mac/#documentation/CoreFoundation/Reference/CFArrayRef/Reference/reference.html
-[CFDictionary]: http://developer.apple.com/library/mac/#documentation/CoreFoundation/Reference/CFDictionaryRef/Reference/reference.html
-[CFDictionaryCreate]: http://developer.apple.com/library/mac/documentation/CoreFoundation/Reference/CFDictionaryRef/Reference/reference.html#//apple_ref/c/func/CFDictionaryCreate
-[-mutableCopy]: http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSObject_Class/Reference/Reference.html%23//apple_ref/occ/instm/NSObject/mutableCopy
-[-copy]: http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSObject_Class/Reference/Reference.html%23//apple_ref/occ/instm/NSObject/copy
-[-retain]: http://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Protocols/NSObject_Protocol/Reference/NSObject.html#//apple_ref/occ/intfm/NSObject/retain
-[-release]: http://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Protocols/NSObject_Protocol/Reference/NSObject.html#//apple_ref/occ/intfm/NSObject/release
-[-isEqual:]: http://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Protocols/NSObject_Protocol/Reference/NSObject.html#//apple_ref/occ/intfm/NSObject/isEqual:
-[-hash]: http://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Protocols/NSObject_Protocol/Reference/NSObject.html#//apple_ref/occ/intfm/NSObject/hash
-[NSArray]: http://developer.apple.com/mac/library/documentation/Cocoa/Reference/Foundation/Classes/NSArray_Class/index.html
-[NSDictionary]: http://developer.apple.com/mac/library/documentation/Cocoa/Reference/Foundation/Classes/NSDictionary_Class/index.html
-[NSData]: http://developer.apple.com/mac/library/documentation/Cocoa/Reference/Foundation/Classes/NSData_Class/index.html
-[printf]: http://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man3/printf.3.html
View
166 Frameworks/JSONKit-1.4/JSONKit.h
@@ -1,166 +0,0 @@
-//
-// JSONKit.h
-// http://github.com/johnezang/JSONKit
-// Licensed under the terms of the BSD License, as specified below.
-//
-
-/*
- Copyright (c) 2011, John Engelhart
-
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the Zang Industries nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
- TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include <stddef.h>
-#include <stdint.h>
-#include <limits.h>
-#include <TargetConditionals.h>
-#include <AvailabilityMacros.h>
-
-#ifdef __OBJC__
-#import <Foundation/NSArray.h>
-#import <Foundation/NSData.h>
-#import <Foundation/NSDictionary.h>
-#import <Foundation/NSError.h>
-#import <Foundation/NSObjCRuntime.h>
-#import <Foundation/NSString.h>
-#endif // __OBJC__
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-// For Mac OS X < 10.5.
-#ifndef NSINTEGER_DEFINED
-#define NSINTEGER_DEFINED
-#if defined(__LP64__) || defined(NS_BUILD_32_LIKE_64)
-typedef long NSInteger;
-typedef unsigned long NSUInteger;
-#define NSIntegerMin LONG_MIN
-#define NSIntegerMax LONG_MAX
-#define NSUIntegerMax ULONG_MAX
-#else // defined(__LP64__) || defined(NS_BUILD_32_LIKE_64)
-typedef int NSInteger;
-typedef unsigned int NSUInteger;
-#define NSIntegerMin INT_MIN
-#define NSIntegerMax INT_MAX
-#define NSUIntegerMax UINT_MAX
-#endif // defined(__LP64__) || defined(NS_BUILD_32_LIKE_64)
-#endif // NSINTEGER_DEFINED
-
-
-#ifndef _JSONKIT_H_
-#define _JSONKIT_H_
-
-#define JSONKIT_VERSION_MAJOR 1
-#define JSONKIT_VERSION_MINOR 4
-
-typedef NSUInteger JKFlags;
-
-/*
- JKParseOptionComments : Allow C style // and /_* ... *_/ (without a _, obviously) comments in JSON.
- JKParseOptionUnicodeNewlines : Allow Unicode recommended (?:\r\n|[\n\v\f\r\x85\p{Zl}\p{Zp}]) newlines.
- JKParseOptionLooseUnicode : Normally the decoder will stop with an error at any malformed Unicode.
- This option allows JSON with malformed Unicode to be parsed without reporting an error.
- Any malformed Unicode is replaced with \uFFFD, or "REPLACEMENT CHARACTER".
- */
-
-enum {
- JKParseOptionNone = 0,
- JKParseOptionStrict = 0,
- JKParseOptionComments = (1 << 0),
- JKParseOptionUnicodeNewlines = (1 << 1),
- JKParseOptionLooseUnicode = (1 << 2),
- JKParseOptionPermitTextAfterValidJSON = (1 << 3),
- JKParseOptionValidFlags = (JKParseOptionComments | JKParseOptionUnicodeNewlines | JKParseOptionLooseUnicode | JKParseOptionPermitTextAfterValidJSON),
-};
-typedef JKFlags JKParseOptionFlags;
-
-enum {
- JKSerializeOptionNone = 0,
- JKSerializeOptionPretty = (1 << 0), // Not implemented yet...
- JKSerializeOptionEscapeUnicode = (1 << 1),
- JKSerializeOptionValidFlags = (JKSerializeOptionPretty | JKSerializeOptionEscapeUnicode),
-};
-typedef JKFlags JKSerializeOptionFlags;
-
-#ifdef __OBJC__
-
-typedef struct JKParseState JKParseState; // Opaque internal, private type.
-
-// As a general rule of thumb, if you use a method that doesn't accept a JKParseOptionFlags argument, it defaults to JKParseOptionStrict
-
-@interface JSONDecoder : NSObject {
- JKParseState *parseState;
-}
-+ (id)decoder;
-+ (id)decoderWithParseOptions:(JKParseOptionFlags)parseOptionFlags;
-- (id)initWithParseOptions:(JKParseOptionFlags)parseOptionFlags;
-- (void)clearCache;
-- (id)parseUTF8String:(const unsigned char *)string length:(size_t)length;
-- (id)parseUTF8String:(const unsigned char *)string length:(size_t)length error:(NSError **)error;
-// The NSData MUST be UTF8 encoded JSON.
-- (id)parseJSONData:(NSData *)jsonData;
-- (id)parseJSONData:(NSData *)jsonData error:(NSError **)error;
-@end
-
-@interface NSString (JSONKit)
-- (id)objectFromJSONString;
-- (id)objectFromJSONStringWithParseOptions:(JKParseOptionFlags)parseOptionFlags;
-- (id)objectFromJSONStringWithParseOptions:(JKParseOptionFlags)parseOptionFlags error:(NSError **)error;
-@end
-
-@interface NSData (JSONKit)
-// The NSData MUST be UTF8 encoded JSON.
-- (id)objectFromJSONData;
-- (id)objectFromJSONDataWithParseOptions:(JKParseOptionFlags)parseOptionFlags;
-- (id)objectFromJSONDataWithParseOptions:(JKParseOptionFlags)parseOptionFlags error:(NSError **)error;
-@end
-
-@interface NSArray (JSONKit)
-- (NSData *)JSONData;
-- (NSData *)JSONDataWithOptions:(JKSerializeOptionFlags)serializeOptions error:(NSError **)error;
-- (NSString *)JSONString;
-- (NSString *)JSONStringWithOptions:(JKSerializeOptionFlags)serializeOptions error:(NSError **)error;
-@end
-
-@interface NSDictionary (JSONKit)
-- (NSData *)JSONData;
-- (NSData *)JSONDataWithOptions:(JKSerializeOptionFlags)serializeOptions error:(NSError **)error;
-- (NSString *)JSONString;
-- (NSString *)JSONStringWithOptions:(JKSerializeOptionFlags)serializeOptions error:(NSError **)error;
-@end
-
-#endif // __OBJC__
-
-#endif // _JSONKIT_H_
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
View
210 Frameworks/JSONKit-1.4/README.md
@@ -1,210 +0,0 @@
-# JSONKit
-
-### A Very High Performance Objective-C JSON Library
-
-JSONKit is licensed under the terms of the BSD License. Copyright &copy; 2011, John Engelhart.
-
-JavaScript Object Notation, or [JSON][], is a lightweight, text-based, serialization format for structured data that is used by many web-based services and API's. It is defined by [RFC 4627][].
-
-JSON provides the following primitive types:
-
-* `null`
-* Boolean `true` and `false`
-* Number
-* String
-* Array
-* Object (a.k.a. Associative Arrays, Key / Value Hash Tables, Maps, Dictionaries, etc.)
-
-These primitive types are mapped to the following Objective-C Foundation classes:
-
-<table>
-<tr><th>JSON</th><th>Objective-C</th></tr>
-<tr><td><code>null</code></td><td><a href="http://developer.apple.com/mac/library/documentation/Cocoa/Reference/Foundation/Classes/NSNull_Class/index.html"><code>NSNull</code></a></td></tr>
-<tr><td><code>true</code> and <code>false</code></td><td><a href="http://developer.apple.com/mac/library/documentation/Cocoa/Reference/Foundation/Classes/NSNumber_Class/index.html"><code>NSNumber</code></a></td></tr>
-<tr><td>Number</td><td><a href="http://developer.apple.com/mac/library/documentation/Cocoa/Reference/Foundation/Classes/NSNumber_Class/index.html"><code>NSNumber</code></a></td></tr>
-<tr><td>String</td><td><a href="http://developer.apple.com/mac/library/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/index.html"><code>NSString</code></a></td></tr>
-<tr><td>Array</td><td><a href="http://developer.apple.com/mac/library/documentation/Cocoa/Reference/Foundation/Classes/NSArray_Class/index.html"><code>NSArray</code></a></td></tr>
-<tr><td>Object</td><td><a href="http://developer.apple.com/mac/library/documentation/Cocoa/Reference/Foundation/Classes/NSDictionary_Class/index.html"><code>NSDictionary</code></a></td></tr>
-</table>
-
-JSONKit uses Core Foundation internally, and it is assumed that Core Foundation &equiv; Foundation for every equivalent base type, i.e. [`CFString`][CFString] &equiv; [`NSString`][NSString].
-
-The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC 2119][].
-
-### JSON To Objective-C Primitive Mapping Details
-
-* The [JSON specification][RFC 4627] is somewhat ambiguous about the details and requirements when it comes to Unicode, and it does not specify how Unicode issues and errors should be handled. Most of the ambiguity stems from the interpretation and scope [RFC 4627][] Section 3, Encoding: `JSON text SHALL be encoded in Unicode.` It is the authors opinion and interpretation that the language of [RFC 4627][] requires that a JSON implementation MUST follow the requirements specified in the [Unicode Standard][], and in particular the [Conformance][Unicode Standard - Conformance] chapter of the [Unicode Standard][], which specifies requirements related to handling, interpreting, and manipulating Unicode text.
-
- The default behavior for JSONKit is strict [RFC 4627][] conformance. It is the authors opinion and interpretation that [RFC 4627][] requires JSON to be encoded in Unicode, and therefore JSON that is not legal Unicode as defined by the [Unicode Standard][] is invalid JSON. Therefore, JSONKit will not accept JSON that contains ill-formed Unicode. The default, strict behavior implies that the `JKParseOptionLooseUnicode` option is not enabled.
-
- When the `JKParseOptionLooseUnicode` option is enabled, JSONKit follows the specifications and recommendations given in [The Unicode 6.0 standard, Chapter 3 - Conformance][Unicode Standard - Conformance], section 3.9 *Unicode Encoding Forms*. As a general rule of thumb, the Unicode code point `U+FFFD` is substituted for any ill-formed Unicode encountered. JSONKit attempts to follow the recommended *Best Practice for Using U+FFFD*: ***Replace each maximal subpart of an ill-formed subsequence by a single U+FFFD.***
-
- The following Unicode code points are treated as ill-formed Unicode, and if `JKParseOptionLooseUnicode` is enabled, cause `U+FFFD` to be substituted in their place:
-
- `U+0000`.<br>
- `U+D800` thru `U+DFFF`, inclusive.<br>
- `U+FDD0` thru `U+FDEF`, inclusive.<br>
- <code>U+<i>n</i>FFFE</code> and <code>U+<i>n</i>FFFF</code>, where *n* is from `0x0` to `0x10`
-
- The code points `U+FDD0` thru `U+FDEF`, <code>U+<i>n</i>FFFE</code>, and <code>U+<i>n</i>FFFF</code> (where *n* is from `0x0` to `0x10`), are defined as ***Noncharacters*** by the Unicode standard and "should never be interchanged".
-
- An exception is made for the code point `U+0000`, which is legal Unicode. The reason for this is that this particular code point is used by C string handling code to specify the end of the string, and any such string handling code will incorrectly stop processing a string at the point where `U+0000` occurs. Although reasonable people may have different opinions on this point, it is the authors considered opinion that the risks of permitting JSON Strings that contain `U+0000` outweigh the benefits. One of the risks in allowing `U+0000` to appear unaltered in a string is that it has the potential to create security problems by subtly altering the semantics of the string which can then be exploited by a malicious attacker. This is similar to the issue of [arbitrarily deleting characters from Unicode text][Unicode_UTR36_Deleting].
-
- [RFC 4627][] allows for these limitations under section 4, Parsers: `An implementation may set limits on the length and character contents of strings.`
-
- It is important to note that JSONKit will not delete characters from the JSON being parsed as this is a [requirement specified by the Unicode Standard][Unicode_UTR36_Deleting]. Additional information can be found in the [Unicode Security FAQ][Unicode_Security_FAQ] and [Unicode Technical Report #36 - Unicode Security Consideration][Unicode_UTR36], in particular the section on [non-visual security][Unicode_UTR36_NonVisualSecurity].
-
-* The [JSON specification][RFC 4627] does not specify the details or requirements for JSON String values, other than such strings must consist of Unicode code points, nor does it specify how errors should be handled. While JSONKit makes an effort (subject to the reasonable caveats above regarding Unicode) to preserve the parsed JSON String exactly, it can not guarantee that [`NSString`][NSString] will preserve the exact Unicode semantics of the original JSON String.
-
- JSONKit does not perform any form of Unicode Normalization on the parsed JSON Strings, but can not make any guarantees that the [`NSString`][NSString] class will not perform Unicode Normalization on the parsed JSON String used to instantiate the [`NSString`][NSString] object. The [`NSString`][NSString] class may place additional restrictions or otherwise transform the JSON String in such a way so that the JSON String is not bijective with the instantiated [`NSString`][NSString] object. In other words, JSONKit can not guarantee that when you round trip a JSON String to a [`NSString`][NSString] and then back to a JSON String that the two JSON Strings will be exactly the same, even though in practice they are. For clarity, "exactly" in this case means bit for bit identical. JSONKit can not even guarantee that the two JSON Strings will be [Unicode equivalent][Unicode_equivalence], even though in practice they will be and would be the most likely cause for the two round tripped JSON Strings to no longer be bit for bit identical.
-
-* JSONKit maps `true` and `false` to the [`CFBoolean`][CFBoolean] values [`kCFBooleanTrue`][kCFBooleanTrue] and [`kCFBooleanFalse`][kCFBooleanFalse], respectively. Conceptually, [`CFBoolean`][CFBoolean] values can be thought of, and treated as, [`NSNumber`][NSNumber] class objects. The benefit to using [`CFBoolean`][CFBoolean] is that `true` and `false` JSON values can be round trip deserialized and serialized without conversion or promotion to a [`NSNumber`][NSNumber] with a value of `0` or `1`.
-
-* The [JSON specification][RFC 4627] does not specify the details or requirements for JSON Number values, nor does it specify how errors due to conversion should be handled. In general, JSONKit will not accept JSON that contains JSON Number values that it can not convert with out error or loss of precision.
-
- For non-floating-point numbers (i.e., JSON Number values that do not include a `.` or `e|E`), JSONKit uses a 64-bit C primitive type internally, regardless of whether the target architecture is 32-bit or 64-bit. For unsigned values (i.e., those that do not begin with a `-`), this allows for values up to <code>2<sup>64</sup>-1</code> and up to <code>-2<sup>63</sup></code> for negative values. As a special case, the JSON Number `-0` is treated as a floating-point number since the underlying floating-point primitive type is capable of representing a negative zero, whereas the underlying twos-complement non-floating-point primitive type can not. JSON that contains Number values that exceed these limits will fail to parse and optionally return a [`NSError`][NSError] object. The functions [`strtoll()`][strtoll] and [`strtoull()`][strtoull] are used to perform the conversions.
-
- The C `double` primitive type, or [IEEE 754 Double 64-bit floating-point][Double Precision], is used to represent floating-point JSON Number values. JSON that contains floating-point Number values that can not be represented as a `double` (i.e., due to over or underflow) will fail to parse and optionally return a [`NSError`][NSError] object. The function [`strtod()`][strtod] is used to perform the conversion. Note that the JSON standard does not allow for infinities or `NaN` (Not a Number).
-
-* For JSON Objects (or [`NSDictionary`][NSDictionary] in JSONKit nomenclature), [RFC 4627][] says `The names within an object SHOULD be unique` (note: `name` is a `key` in JSONKit nomenclature). At this time the JSONKit behavior is `undefined` for JSON that contains names within an object that are not unique. However, JSONKit currently tries to follow a "the last key / value pair parsed is the one chosen" policy. This behavior is not finalized and should not be depended on.
-
- The previously covered limitations regarding JSON Strings have important consequences for JSON Objects since JSON Strings are used as the `key`. The [JSON specification][RFC 4627] does not specify the details or requirements for JSON Strings used as `keys` in JSON Objects, specifically what it means for two `keys` to compare equal. Unfortunately, because [RFC 4627][] states `JSON text SHALL be encoded in Unicode.`, this means that one must use the [Unicode Standard][] to interpret the JSON, and the [Unicode Standard][] allows for strings that are encoded with different Unicode Code Points to "compare equal". JSONKit uses [`NSString`][NSString] exclusively to manage the parsed JSON Strings. Because [`NSString`][NSString] is focused capatability with the [Unicode Standard][], there exists the possibility that [`NSString`][NSString] may subtly and silently convert the Unicode Code Points contained in the original JSON String in to a [Unicode equivalent][Unicode_equivalence] string. Due to this, the JSONKit behavior for JSON Strings used as `keys` in JSON Objects that may be [Unicode equivalent][Unicode_equivalence] but not binary equivalent is `undefined`.
-
-### Objective-C To JSON Primitive Mapping Details
-
-* The [`NSDictionary`][NSDictionary] class allows for any object, which can be of any class, to be used as a `key`. JSON, however, only permits Strings to be used as `keys`. Therefore JSONKit will fail with an error if it encounters a [`NSDictionary`][NSDictionary] that contains keys that are not [`NSString`][NSString] objects during serialization.
-
-* JSON does not allow for Numbers that are <code>&plusmn;Infinity</code> or <code>&plusmn;NaN</code>. Therefore JSONKit will fail with an error if it encounters a [`NSNumber`][NSNumber] that contains such a value during serialization.
-
-* JSONKit will fail with an error if it encounters an object that is not a [`NSNull`][NSNull], [`NSNumber`][NSNumber], [`NSString`][NSString], [`NSArray`][NSArray], or [`NSDictionary`][NSDictionary] class object during serialization.
-
-* Objects created with [`[NSNumber numberWithBool:YES]`][NSNumber_numberWithBool] and [`[NSNumber numberWithBool:NO]`][NSNumber_numberWithBool] will be mapped to the JSON values of `true` and `false`, respectively.
-
-### Reporting Bugs
-
-Please use the [github.com JSONKit Issue Tracker](https://github.com/johnezang/JSONKit/issues) to report bugs.
-
-The author requests that you do not file a bug report with JSONKit regarding problems reported by the `clang` static analyzer unless you first manually verify that it is an actual, bona-fide problem with JSONKit and, if appropriate, is not "legal" C code as defined by the C99 language specification. If the `clang` static analyzer is reporting a problem with JSONKit that is not an actual, bona-fide problem and is perfectly legal code as defined by the C99 language specification, then the appropriate place to file a bug report or complaint is with the developers of the `clang` static analyzer.
-
-### Important Details
-
-* JSONKit is not designed to be used with the Mac OS X Garbage Collection. The behavior of JSONKit when compiled with `-fobj-gc` is `undefined`. It is extremely unlikely that Mac OS X Garbage Collection will ever be supported.
-
-* The JSON to be parsed by JSONKit MUST be encoded as Unicode. In the unlikely event you end up with JSON that is not encoded as Unicode, you must first convert the JSON to Unicode, preferably as `UTF8`. One way to accomplish this is with the [`NSString`][NSString] methods [`-initWithBytes:length:encoding:`][NSString_initWithBytes] and [`-initWithData:encoding:`][NSString_initWithData].
-
-* Internally, the low level parsing engine uses `UTF8` exclusively. The `JSONDecoder` method `-parseJSONData:` takes a [`NSData`][NSData] object as its argument and it is assumed that the raw bytes contained in the [`NSData`][NSData] is `UTF8` encoded, otherwise the behavior is `undefined`.
-
-* It is not safe to use the same instantiated `JSONDecoder` object from multiple threads at the same time. If you wish to share a `JSONDecoder` between threads, you are responsible for adding mutex barriers to ensure that only one thread is decoding JSON using the shared `JSONDecoder` object at a time.
-
-### Tips for speed
-
-* Enable the `NS_BLOCK_ASSERTIONS` pre-processor flag. JSONKit makes heavy use of [`NSCParameterAssert()`][NSCParameterAssert] internally to ensure that various arguments, variables, and other state contains only legal and expected values. If an assertion check fails it causes a run time exception that will normally cause a program to terminate. These checks and assertions come with a price: they take time to execute and do not contribute to the work being performed. It is perfectly safe to enable `NS_BLOCK_ASSERTIONS` as JSONKit always performs checks that are required for correct operation. The checks performed with [`NSCParameterAssert()`][NSCParameterAssert] are completely optional and are meant to be used in "debug" builds where extra integrity checks are usually desired. While your mileage may vary, the author has found that adding `-DNS_BLOCK_ASSERTIONS` to an `-O2` optimization setting can generally result in an approximate <span style="white-space: nowrap;">7-12%</span> increase in performance.
-
-* Since the very low level parsing engine works exclusively with `UTF8` byte streams, anything that is not already encoded as `UTF8` must first be converted to `UTF8`. While JSONKit provides additions to the [`NSString`][NSString] class which allows you to conveniently convert JSON contained in a [`NSString`][NSString], this convenience does come with a price. JSONKit uses the [`-UTF8String`][NSString_UTF8String] method to obtain a `UTF8` encoded version of a [`NSString`][NSString], and while the details of how a strings performs that conversion are an internal implementation detail, it is likely that this conversion carries a cost both in terms of time and the memory needed to store the conversion result. Therefore, if speed is a priority, you should avoid using the [`NSString`][NSString] convenience methods if possible.
-
-* If you are receiving JSON data from a web server, and you are able to determine that the raw bytes returned by the web server is JSON encoded as `UTF8`, you should use the `JSONDecoder` method `-parseUTF8String:length:` which immediately begins parsing the pointers bytes. In practice, every JSONKit method that converts JSON to an Objective-C object eventually calls this method to perform the conversion.
-
-* If you are using one of the various ways provided by the `NSURL` family of classes to receive JSON results from a web server, which typically return the results in the form of a [`NSData`][NSData] object, and you are able to determine that the raw bytes contained in the [`NSData`][NSData] are encoded as `UTF8`, then you should use either the `JSONDecoder` method `parseJSONData:` or the [`NSData`][NSData] method `-objectFromJSONData`. If are going to be converting a lot of JSON, the better choice is to instantiate a `JSONDecoder` object once and use the same instantiated object to perform all your conversions. This has two benefits:
- 1. The [`NSData`][NSData] method `-objectFromJSONData` creates an autoreleased `JSONDecoder` object to perform the one time conversion. By instantiating a `JSONDecoder` object once and using the `parseJSONData:` method repeatedly, you can avoid this overhead.
- 2. The instantiated object cache from the previous JSON conversion is reused. This can result in both better performance and a reduction in memory usage if the JSON your are converting is very similar. A typical example might be if you are converting JSON at periodic intervals that consists of real time status updates.
-
-* On average, the <code>JSONData&hellip;</code> methods are nearly four times faster than the <code>JSONString&hellip;</code> methods when serializing a [`NSDictionary`][NSDictionary] or [`NSArray`][NSArray] to JSON. The difference in speed is due entirely to the instantiation overhead of [`NSString`][NSString].
-
-### Parsing Interface
-
-#### JSONDecoder Interface
-
-**Note:** The bytes contained in a [`NSData`][NSData] object ***MUST*** be `UTF8` encoded.
-
-**Important:** Methods will raise [`NSInvalidArgumentException`][NSInvalidArgumentException] if `parseOptionFlags` is not valid.
-**Important:** `parseUTF8String:` will raise [`NSInvalidArgumentException`][NSInvalidArgumentException] if `parseUTF8String` is `NULL`.
-**Important:** `parseJSONData:` will raise [`NSInvalidArgumentException`][NSInvalidArgumentException] if `jsonData` is `NULL`.
-
-<pre>+ (id)decoder;
-+ (id)decoderWithParseOptions:(JKParseOptionFlags)parseOptionFlags;
-- (id)initWithParseOptions:(JKParseOptionFlags)parseOptionFlags;
-
-- (void)clearCache;
-
-- (id)parseUTF8String:(const unsigned char *)string length:(size_t)length;
-- (id)parseUTF8String:(const unsigned char *)string length:(size_t)length error:(NSError **)error;
-
-- (id)parseJSONData:(NSData *)jsonData;
-- (id)parseJSONData:(NSData *)jsonData error:(NSError **)error;</pre>
-
-#### NSString Interface
-
-<pre>- (id)objectFromJSONString;
-- (id)objectFromJSONStringWithParseOptions:(JKParseOptionFlags)parseOptionFlags;
-- (id)objectFromJSONStringWithParseOptions:(JKParseOptionFlags)parseOptionFlags error:(NSError **)error;</pre>
-
-#### NSData Interface
-
-<pre>- (id)objectFromJSONData;
-- (id)objectFromJSONDataWithParseOptions:(JKParseOptionFlags)parseOptionFlags;
-- (id)objectFromJSONDataWithParseOptions:(JKParseOptionFlags)parseOptionFlags error:(NSError **)error;</pre>
-
-#### JKParseOptionFlags
-
-<table>
- <tr><th>Parsing Option</th><th>Description</th></tr>
- <tr><td><code>JKParseOptionNone</code></td><td>This is the default if no other other parse option flags are specified, and the option used when a convenience method does not provide an argument for explicitly specifying the parse options to use. Synonymous with <code>JKParseOptionStrict</code>.</td></tr>
- <tr><td><code>JKParseOptionStrict</code></td><td>The JSON will be parsed in strict accordance with the <a href="http://tools.ietf.org/html/rfc4627">RFC 4627</a> specification.</td></tr>
- <tr><td><code>JKParseOptionComments</code></td><td>Allow C style <code>//</code> and <code>/* &hellip; */</code> comments in JSON. This is a fairly common extension to JSON, but JSON that contains C style comments is not strictly conforming JSON.</td></tr>
- <tr><td><code>JKParseOptionUnicodeNewlines</code></td><td>Allow Unicode recommended <code>(?:\r\n|[\n\v\f\r\x85\p{Zl}\p{Zp}])</code> newlines in JSON. The <a href="http://tools.ietf.org/html/rfc4627">JSON specification</a> only allows the newline characters <code>\r</code> and <code>\n</code>, but this option allows JSON that contains the <a href="http://en.wikipedia.org/wiki/Newline#Unicode">Unicode recommended newline characters</a> to be parsed. JSON that contains these additional newline characters is not strictly conforming JSON.</td></tr>
- <tr><td><code>JKParseOptionLooseUnicode</code></td><td>Normally the decoder will stop with an error at any malformed Unicode. This option allows JSON with malformed Unicode to be parsed without reporting an error. Any malformed Unicode is replaced with <code>\uFFFD</code>, or <code>REPLACEMENT CHARACTER</code>, as specified in <a href="http://www.unicode.org/versions/Unicode6.0.0/ch03.pdf">The Unicode 6.0 standard, Chapter 3</a>, section 3.9 <em>Unicode Encoding Forms</em>.</td></tr>
- <tr><td><code>JKParseOptionPermitTextAfterValidJSON</code></td><td>Normally, <code>white-space</code> that follows the JSON is interpreted as a parsing failure. This option allows for any trailing <code>white-space</code> to be ignored and not cause a parsing error.</td></tr>
-</table>
-
-### Serializing Interface
-
-**Note:** The bytes contained in the returned [`NSData`][NSData] object is `UTF8` encoded.
-
-#### NSArray and NSDictionary Interface
-
-<pre>- (NSData *)JSONData;
-- (NSData *)JSONDataWithOptions:(JKSerializeOptionFlags)serializeOptions error:(NSError **)error;
-- (NSString *)JSONString;
-- (NSString *)JSONStringWithOptions:(JKSerializeOptionFlags)serializeOptions error:(NSError **)error;</pre>
-
-#### JKSerializeOptionFlags
-
-<table>
- <tr><th>Serializing Option</th><th>Description</th></tr>
- <tr><td><code>JKSerializeOptionNone</code></td><td>This is the default if no other other serialize option flags are specified, and the option used when a convenience method does not provide an argument for explicitly specifying the serialize options to use.</td></tr>
- <tr><td><code>JKSerializeOptionEscapeUnicode</code></td><td>When JSONKit encounters Unicode characters in <a href="http://developer.apple.com/mac/library/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/index.html"><code>NSString</code></a> objects, the default behavior is to encode those Unicode characters as <code>UTF8</code>. This option causes JSONKit to encode those characters as <code>\u<i>XXXX</i></code>. For example,<br/><code>["w&isin;L&#10234;y(&#8739;y&#8739;&le;&#8739;w&#8739;)"]</code><br/>becomes:<br/><code>["w\u2208L\u27fa\u2203y(\u2223y\u2223\u2264\u2223w\u2223)"]</code></td></tr>
-</table>
-
-[JSON]: http://www.json.org/
-[RFC 4627]: http://tools.ietf.org/html/rfc4627
-[RFC 2119]: http://tools.ietf.org/html/rfc2119
-[Double Precision]: http://en.wikipedia.org/wiki/Double_precision
-[CFBoolean]: http://developer.apple.com/mac/library/documentation/CoreFoundation/Reference/CFBooleanRef/index.html
-[kCFBooleanTrue]: http://developer.apple.com/mac/library/documentation/CoreFoundation/Reference/CFBooleanRef/Reference/reference.html#//apple_ref/doc/c_ref/kCFBooleanTrue
-[kCFBooleanFalse]: http://developer.apple.com/mac/library/documentation/CoreFoundation/Reference/CFBooleanRef/Reference/reference.html#//apple_ref/doc/c_ref/kCFBooleanFalse
-[Unicode Standard]: http://www.unicode.org/versions/Unicode6.0.0/
-[Unicode Standard - Conformance]: http://www.unicode.org/versions/Unicode6.0.0/ch03.pdf
-[Unicode_equivalence]: http://en.wikipedia.org/wiki/Unicode_equivalence
-[Unicode_UTR36]: http://www.unicode.org/reports/tr36/
-[Unicode_UTR36_NonVisualSecurity]: http://www.unicode.org/reports/tr36/#Canonical_Represenation
-[Unicode_UTR36_Deleting]: http://www.unicode.org/reports/tr36/#Deletion_of_Noncharacters
-[Unicode_Security_FAQ]: http://www.unicode.org/faq/security.html
-[NSNull]: http://developer.apple.com/mac/library/documentation/Cocoa/Reference/Foundation/Classes/NSNull_Class/index.html
-[NSNumber]: http://developer.apple.com/mac/library/documentation/Cocoa/Reference/Foundation/Classes/NSNumber_Class/index.html
-[NSNumber_numberWithBool]: http://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSNumber_Class/Reference/Reference.html#//apple_ref/occ/clm/NSNumber/numberWithBool:
-[NSString]: http://developer.apple.com/mac/library/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/index.html
-[NSString_initWithBytes]: http://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/Reference/NSString.html#//apple_ref/occ/instm/NSString/initWithBytes:length:encoding:
-[NSString_initWithData]: http://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/Reference/NSString.html#//apple_ref/occ/instm/NSString/initWithData:encoding:
-[NSString_UTF8String]: http://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/Reference/NSString.html#//apple_ref/occ/instm/NSString/UTF8String
-[NSArray]: http://developer.apple.com/mac/library/documentation/Cocoa/Reference/Foundation/Classes/NSArray_Class/index.html
-[NSDictionary]: http://developer.apple.com/mac/library/documentation/Cocoa/Reference/Foundation/Classes/NSDictionary_Class/index.html
-[NSError]: http://developer.apple.com/mac/library/documentation/Cocoa/Reference/Foundation/Classes/NSError_Class/index.html
-[NSData]: http://developer.apple.com/mac/library/documentation/Cocoa/Reference/Foundation/Classes/NSData_Class/index.html
-[NSInvalidArgumentException]: http://developer.apple.com/mac/library/documentation/Cocoa/Reference/Foundation/Miscellaneous/Foundation_Constants/Reference/reference.html#//apple_ref/doc/c_ref/NSInvalidArgumentException
-[CFString]: http://developer.apple.com/library/mac/#documentation/CoreFoundation/Reference/CFStringRef/Reference/reference.html
-[strtoll]: http://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man3/strtoll.3.html
-[strtod]: http://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man3/strtod.3.html
-[strtoull]: http://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man3/strtoull.3.html
-[NSCParameterAssert]: http://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Miscellaneous/Foundation_Functions/Reference/reference.html#//apple_ref/c/macro/NSCParameterAssert
-[UnicodeNewline]: http://en.wikipedia.org/wiki/Newline#Unicode
-[-mutableCopy]: http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSObject_Class/Reference/Reference.html%23//apple_ref/occ/instm/NSObject/mutableCopy
View
251 Frameworks/JSONKit-20110725/JSONKit.h
@@ -0,0 +1,251 @@
+//
+// JSONKit.h
+// http://github.com/johnezang/JSONKit
+// Dual licensed under either the terms of the BSD License, or alternatively
+// under the terms of the Apache License, Version 2.0, as specified below.
+//
+
+/*
+ Copyright (c) 2011, John Engelhart
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the Zang Industries nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/*
+ Copyright 2011 John Engelhart
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+#include <stddef.h>
+#include <stdint.h>
+#include <limits.h>
+#include <TargetConditionals.h>
+#include <AvailabilityMacros.h>
+
+#ifdef __OBJC__
+#import <Foundation/NSArray.h>
+#import <Foundation/NSData.h>
+#import <Foundation/NSDictionary.h>
+#import <Foundation/NSError.h>
+#import <Foundation/NSObjCRuntime.h>
+#import <Foundation/NSString.h>
+#endif // __OBJC__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+// For Mac OS X < 10.5.
+#ifndef NSINTEGER_DEFINED
+#define NSINTEGER_DEFINED
+#if defined(__LP64__) || defined(NS_BUILD_32_LIKE_64)
+typedef long NSInteger;
+typedef unsigned long NSUInteger;
+#define NSIntegerMin LONG_MIN
+#define NSIntegerMax LONG_MAX
+#define NSUIntegerMax ULONG_MAX
+#else // defined(__LP64__) || defined(NS_BUILD_32_LIKE_64)
+typedef int NSInteger;
+typedef unsigned int NSUInteger;
+#define NSIntegerMin INT_MIN
+#define NSIntegerMax INT_MAX
+#define NSUIntegerMax UINT_MAX
+#endif // defined(__LP64__) || defined(NS_BUILD_32_LIKE_64)
+#endif // NSINTEGER_DEFINED
+
+
+#ifndef _JSONKIT_H_
+#define _JSONKIT_H_
+
+#if defined(__GNUC__) && (__GNUC__ >= 4) && defined(__APPLE_CC__) && (__APPLE_CC__ >= 5465)
+#define JK_DEPRECATED_ATTRIBUTE __attribute__((deprecated))
+#else
+#define JK_DEPRECATED_ATTRIBUTE
+#endif
+
+#define JSONKIT_VERSION_MAJOR 1
+#define JSONKIT_VERSION_MINOR 4
+
+typedef NSUInteger JKFlags;
+
+/*
+ JKParseOptionComments : Allow C style // and /_* ... *_/ (without a _, obviously) comments in JSON.
+ JKParseOptionUnicodeNewlines : Allow Unicode recommended (?:\r\n|[\n\v\f\r\x85\p{Zl}\p{Zp}]) newlines.
+ JKParseOptionLooseUnicode : Normally the decoder will stop with an error at any malformed Unicode.
+ This option allows JSON with malformed Unicode to be parsed without reporting an error.
+ Any malformed Unicode is replaced with \uFFFD, or "REPLACEMENT CHARACTER".
+ */
+
+enum {
+ JKParseOptionNone = 0,
+ JKParseOptionStrict = 0,
+ JKParseOptionComments = (1 << 0),
+ JKParseOptionUnicodeNewlines = (1 << 1),
+ JKParseOptionLooseUnicode = (1 << 2),
+ JKParseOptionPermitTextAfterValidJSON = (1 << 3),
+ JKParseOptionValidFlags = (JKParseOptionComments | JKParseOptionUnicodeNewlines | JKParseOptionLooseUnicode | JKParseOptionPermitTextAfterValidJSON),
+};
+typedef JKFlags JKParseOptionFlags;
+
+enum {
+ JKSerializeOptionNone = 0,
+ JKSerializeOptionPretty = (1 << 0),
+ JKSerializeOptionEscapeUnicode = (1 << 1),
+ JKSerializeOptionEscapeForwardSlashes = (1 << 4),
+ JKSerializeOptionValidFlags = (JKSerializeOptionPretty | JKSerializeOptionEscapeUnicode | JKSerializeOptionEscapeForwardSlashes),
+};
+typedef JKFlags JKSerializeOptionFlags;
+
+#ifdef __OBJC__
+
+typedef struct JKParseState JKParseState; // Opaque internal, private type.
+
+// As a general rule of thumb, if you use a method that doesn't accept a JKParseOptionFlags argument, it defaults to JKParseOptionStrict
+
+@interface JSONDecoder : NSObject {
+ JKParseState *parseState;
+}
++ (id)decoder;
++ (id)decoderWithParseOptions:(JKParseOptionFlags)parseOptionFlags;
+- (id)initWithParseOptions:(JKParseOptionFlags)parseOptionFlags;
+- (void)clearCache;
+
+// The parse... methods were deprecated in v1.4 in favor of the v1.4 objectWith... methods.
+- (id)parseUTF8String:(const unsigned char *)string length:(size_t)length JK_DEPRECATED_ATTRIBUTE; // Deprecated in JSONKit v1.4. Use objectWithUTF8String:length: instead.
+- (id)parseUTF8String:(const unsigned char *)string length:(size_t)length error:(NSError **)error JK_DEPRECATED_ATTRIBUTE; // Deprecated in JSONKit v1.4. Use objectWithUTF8String:length:error: instead.
+// The NSData MUST be UTF8 encoded JSON.
+- (id)parseJSONData:(NSData *)jsonData JK_DEPRECATED_ATTRIBUTE; // Deprecated in JSONKit v1.4. Use objectWithData: instead.
+- (id)parseJSONData:(NSData *)jsonData error:(NSError **)error JK_DEPRECATED_ATTRIBUTE; // Deprecated in JSONKit v1.4. Use objectWithData:error: instead.
+
+// Methods that return immutable collection objects.
+- (id)objectWithUTF8String:(const unsigned char *)string length:(NSUInteger)length;
+- (id)objectWithUTF8String:(const unsigned char *)string length:(NSUInteger)length error:(NSError **)error;
+// The NSData MUST be UTF8 encoded JSON.
+- (id)objectWithData:(NSData *)jsonData;
+- (id)objectWithData:(NSData *)jsonData error:(NSError **)error;
+
+// Methods that return mutable collection objects.
+- (id)mutableObjectWithUTF8String:(const unsigned char *)string length:(NSUInteger)length;
+- (id)mutableObjectWithUTF8String:(const unsigned char *)string length:(NSUInteger)length error:(NSError **)error;
+// The NSData MUST be UTF8 encoded JSON.
+- (id)mutableObjectWithData:(NSData *)jsonData;
+- (id)mutableObjectWithData:(NSData *)jsonData error:(NSError **)error;
+
+@end
+
+////////////
+#pragma mark Deserializing methods
+////////////
+
+@interface NSString (JSONKitDeserializing)
+- (id)objectFromJSONString;
+- (id)objectFromJSONStringWithParseOptions:(JKParseOptionFlags)parseOptionFlags;
+- (id)objectFromJSONStringWithParseOptions:(JKParseOptionFlags)parseOptionFlags error:(NSError **)error;
+- (id)mutableObjectFromJSONString;
+- (id)mutableObjectFromJSONStringWithParseOptions:(JKParseOptionFlags)parseOptionFlags;
+- (id)mutableObjectFromJSONStringWithParseOptions:(JKParseOptionFlags)parseOptionFlags error:(NSError **)error;
+@end
+
+@interface NSData (JSONKitDeserializing)
+// The NSData MUST be UTF8 encoded JSON.
+- (id)objectFromJSONData;
+- (id)objectFromJSONDataWithParseOptions:(JKParseOptionFlags)parseOptionFlags;
+- (id)objectFromJSONDataWithParseOptions:(JKParseOptionFlags)parseOptionFlags error:(NSError **)error;
+- (id)mutableObjectFromJSONData;
+- (id)mutableObjectFromJSONDataWithParseOptions:(JKParseOptionFlags)parseOptionFlags;
+- (id)mutableObjectFromJSONDataWithParseOptions:(JKParseOptionFlags)parseOptionFlags error:(NSError **)error;
+@end
+
+////////////
+#pragma mark Serializing methods
+////////////
+
+@interface NSString (JSONKitSerializing)
+// Convenience methods for those that need to serialize the receiving NSString (i.e., instead of having to serialize a NSArray with a single NSString, you can "serialize to JSON" just the NSString).
+// Normally, a string that is serialized to JSON has quotation marks surrounding it, which you may or may not want when serializing a single string, and can be controlled with includeQuotes:
+// includeQuotes:YES `a "test"...` -> `"a \"test\"..."`
+// includeQuotes:NO `a "test"...` -> `a \"test\"...`
+- (NSData *)JSONData; // Invokes JSONDataWithOptions:JKSerializeOptionNone includeQuotes:YES
+- (NSData *)JSONDataWithOptions:(JKSerializeOptionFlags)serializeOptions includeQuotes:(BOOL)includeQuotes error:(NSError **)error;
+- (NSString *)JSONString; // Invokes JSONStringWithOptions:JKSerializeOptionNone includeQuotes:YES
+- (NSString *)JSONStringWithOptions:(JKSerializeOptionFlags)serializeOptions includeQuotes:(BOOL)includeQuotes error:(NSError **)error;
+@end
+
+@interface NSArray (JSONKitSerializing)
+- (NSData *)JSONData;
+- (NSData *)JSONDataWithOptions:(JKSerializeOptionFlags)serializeOptions error:(NSError **)error;
+- (NSData *)JSONDataWithOptions:(JKSerializeOptionFlags)serializeOptions serializeUnsupportedClassesUsingDelegate:(id)delegate selector:(SEL)selector error:(NSError **)error;
+- (NSString *)JSONString;
+- (NSString *)JSONStringWithOptions:(JKSerializeOptionFlags)serializeOptions error:(NSError **)error;
+- (NSString *)JSONStringWithOptions:(JKSerializeOptionFlags)serializeOptions serializeUnsupportedClassesUsingDelegate:(id)delegate selector:(SEL)selector error:(NSError **)error;
+@end
+
+@interface NSDictionary (JSONKitSerializing)
+- (NSData *)JSONData;
+- (NSData *)JSONDataWithOptions:(JKSerializeOptionFlags)serializeOptions error:(NSError **)error;
+- (NSData *)JSONDataWithOptions:(JKSerializeOptionFlags)serializeOptions serializeUnsupportedClassesUsingDelegate:(id)delegate selector:(SEL)selector error:(NSError **)error;
+- (NSString *)JSONString;
+- (NSString *)JSONStringWithOptions:(JKSerializeOptionFlags)serializeOptions error:(NSError **)error;
+- (NSString *)JSONStringWithOptions:(JKSerializeOptionFlags)serializeOptions serializeUnsupportedClassesUsingDelegate:(id)delegate selector:(SEL)selector error:(NSError **)error;
+@end
+
+#ifdef __BLOCKS__
+
+@interface NSArray (JSONKitSerializingBlockAdditions)
+- (NSData *)JSONDataWithOptions:(JKSerializeOptionFlags)serializeOptions serializeUnsupportedClassesUsingBlock:(id(^)(id object))block error:(NSError **)error;
+- (NSString *)JSONStringWithOptions:(JKSerializeOptionFlags)serializeOptions serializeUnsupportedClassesUsingBlock:(id(^)(id object))block error:(NSError **)error;
+@end
+
+@interface NSDictionary (JSONKitSerializingBlockAdditions)
+- (NSData *)JSONDataWithOptions:(JKSerializeOptionFlags)serializeOptions serializeUnsupportedClassesUsingBlock:(id(^)(id object))block error:(NSError **)error;
+- (NSString *)JSONStringWithOptions:(JKSerializeOptionFlags)serializeOptions serializeUnsupportedClassesUsingBlock:(id(^)(id object))block error:(NSError **)error;
+@end
+
+#endif
+
+
+#endif // __OBJC__
+
+#endif // _JSONKIT_H_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
View
1,557 Frameworks/JSONKit-1.4/JSONKit.m → Frameworks/JSONKit-20110725/JSONKit.m
1,111 additions, 446 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
View
41 Frameworks/NextiveJson-20110725/NSError+Extensions.h
@@ -0,0 +1,41 @@
+/*
+
+ Copyright (c) 2011 Nextive LLC
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
+ associated documentation files (the "Software"), to deal in the Software without restriction,
+ including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all copies or substantial
+ portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
+ NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
+ OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ Created by Martin Adoue (martin@nextive.com) and Hernan Pelassini (hernan@nextive.com)
+
+ */
+
+#import <Foundation/Foundation.h>
+#import "NXDebug.h"
+
+/**
+ Extensions to simplfy common tasks with `NSError`
+ */
+@interface NSError (Extensions)
+
+/**
+ Does all the dirty work of creating a simple NSError object.
+ @param domain The error domain.
+ @param code The error code for the error
+ @param description A NSString containing the description of the error
+ @return Returns an NSError object for domain with the specified error code and description
+ */
++(NSError*)errorWithDomain:(NSString*)domain code:(NSInteger)code description:(NSString*)description NOTNULL(1, 3);
+
+@end
View
44 Frameworks/NextiveJson-20110725/NSError+Extensions.m
@@ -0,0 +1,44 @@
+/*
+
+ Copyright (c) 2011 Nextive LLC
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
+ associated documentation files (the "Software"), to deal in the Software without restriction,
+ including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all copies or substantial
+ portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
+ NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
+ OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ Created by Martin Adoue (martin@nextive.com) and Hernan Pelassini (hernan@nextive.com)
+
+ */
+
+#import "NSError+Extensions.h"
+
+
+@implementation NSError(Extensions)
++(NSError*)errorWithDomain:(NSString*)domain code:(NSInteger)code description:(NSString*)description
+{
+
+ ASSERT(domain);
+ ASSERT(description);
+ ASSERT_CLASS(domain, NSString);
+ ASSERT_CLASS(description, NSString);
+ ASSERT([domain length] > 0);
+ ASSERT([description length] > 0);
+ ASSERT(code != 0);
+
+ NSMutableDictionary* errorDict = [NSMutableDictionary dictionary];
+ [errorDict setObject:description forKey:NSLocalizedDescriptionKey];
+ return [NSError errorWithDomain:domain code:code userInfo:errorDict];
+}
+
+@end
View
124 Frameworks/NextiveJson-20110725/NXDebug.h
@@ -0,0 +1,124 @@
+/*
+
+ Copyright (c) 2011 Nextive LLC
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
+ associated documentation files (the "Software"), to deal in the Software without restriction,
+ including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all copies or substantial
+ portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
+ NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
+ OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ Created by Martin Adoue (martin@nextive.com) and Hernan Pelassini (hernan@nextive.com)
+
+ */
+
+#import <Foundation/Foundation.h>
+
+/**
+
+ Small class with helper methods, only useful for debugging.
+
+ */
+@interface NXDebug : NSObject
+{
+
+}
+/// Prints the call stack up to the call. only in supported platforms.
++(void)printCallStack;
+
+@end
+
+
+#ifdef __clang__
+ #define NOTNULL(...) __attribute__((nonnull (__VA_ARGS__)))
+ #define NORETURN __attribute__((analyzer_noreturn))
+#else
+ #define NOTNULL(...)
+ #define NORETURN
+#endif
+
+
+// Prints a message and the call stack to the console, and calls NXDebugBreak
+// INTERNAL. Do not use directly.
+void _NXAssert(NSString *message, const char *filename, int lineNumber, const char *functionName) NOTNULL(1, 2, 4) NORETURN;
+
+// Prints a formatted string to the console.
+// INTERNAL. Do not use directly.
+void _NXTrace(NSString *format, ...) NOTNULL(1);
+
+// INTERNAL. Do not use directly.
+void _NXDie(NSString *reason, const char *filename, int line, const char *function) NOTNULL(1, 2, 4) NORETURN;
+
+
+/*
+ Use this when you have a variable that is only used on certain configurations (tipically DEBUG).
+ It has zero runtime cost.
+
+ Example:
+
+ ----------------------------
+ int length = [string length];
+ ASSERT(length > 0);
+ // If we never use length again, the compiler will complain in release builds.
+ UNUSED(variable);
+ ----------------------------
+
+ Another use is to shut up the compiler when we don't use a parameter.
+
+ */
+#define UNUSED(variable) ((void)variable)
+
+
+/*
+ ASSERT is a nicer version of NSAssertX, with the added benefit that it does nothing on release builds.
+ Oh, one more thing. If you're running on the debugger, you can continue. Yep, it's like a good old conditional breakpoint.
+ */
+#ifndef DEBUG
+ #define ASSERT(condition) do { } while (0);
+#else
+ #define ASSERT(condition) do { if(!(condition)) { _NXAssert([NSString stringWithCString:#condition encoding:NSUTF8StringEncoding], __FILE__, __LINE__, __PRETTY_FUNCTION__); } } while (0);
+#endif
+
+/*
+ TRACE is a nicer version of NSLog, with the added benefit that it does nothing on release builds.
+
+ Usage:
+
+ TRACE();
+ TRACE(@"Hello world");
+ TRACE(@"The value is: %d", value);
+ TRACE("The value is: %d", value);
+
+ */
+#ifndef DEBUG
+#define TRACE(...) do { } while (0);
+#else
+#define TRACE(format, ...) do { _NXTrace((@"%s:%d:1 [%s] " format), __FILE__, __LINE__, __PRETTY_FUNCTION__, ##__VA_ARGS__); } while (0);
+#endif
+
+// Use this when you want to signal an impossible or unexpected situation.
+// It's similar to ASSERT, but it remains on release builds.
+// Prints the reason, the location of the failure, and the call stack to the console.
+// If its running under a debugger, it breaks. Else, it exits.
+// NOTE: it only prints the call stack on iOS4+
+#define DIE(reason) do { _NXDie(reason, __FILE__, __LINE__, __PRETTY_FUNCTION__); } while (0);
+
+
+// Short and clear way to make sure a variable is of the expected type.
+#define ASSERT_CLASS(x, y) ASSERT([x isKindOfClass:[y class]])
+#define ASSERT_CLASS_OR_NULL(x, y) ASSERT(x == nil || [(id)x isKindOfClass:[y class]])
+#define ASSERT_PROTOCOL(x, y) ASSERT([x conformsToProtocol:@protocol(y)]);
+
+// Release and set to nil in a single line.
+#define NXReleaseAndNil(x) { [x release], x = nil; }
+
+
View
131 Frameworks/NextiveJson-20110725/NXDebug.m
@@ -0,0 +1,131 @@
+/*
+
+ Copyright (c) 2011 Nextive LLC
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
+ associated documentation files (the "Software"), to deal in the Software without restriction,
+ including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all copies or substantial
+ portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
+ NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
+ OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ Created by Martin Adoue (martin@nextive.com) and Hernan Pelassini (hernan@nextive.com)
+
+ */
+
+#import "NXDebug.h"
+#include <unistd.h>
+#include <sys/sysctl.h>
+
+bool _NXAmIBeingDebugged(void);
+void _NXDebugBreak(void);
+
+
+// Returns true if the current process is being debugged (either
+// running under the debugger or has a debugger attached post facto).
+// From http://developer.apple.com/mac/library/qa/qa2004/qa1361.html, midly edited for style.
+bool _NXAmIBeingDebugged(void)
+{
+ int mib[4];
+ struct kinfo_proc info;
+
+ // Initialize the flags so that, if sysctl fails for some bizarre
+ // reason, we get a predictable result.
+
+ info.kp_proc.p_flag = 0;
+
+ // Initialize mib, which tells sysctl the info we want, in this case
+ // we're looking for information about a specific process ID.
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_PROC;
+ mib[2] = KERN_PROC_PID;
+ mib[3] = getpid();
+
+ // Call sysctl.
+
+ size_t size = sizeof(info);
+ int junk = sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, NULL, 0);
+ ASSERT(junk == 0);
+ UNUSED(junk);
+
+ // We're being debugged if the P_TRACED flag is set.
+ return ( (info.kp_proc.p_flag & P_TRACED) != 0 );
+}
+
+// If the app is running attached to a debugger, it breaks. If not, it crashes.
+void _NXDebugBreak(void)
+{
+ if (!_NXAmIBeingDebugged())
+ {
+ abort();
+ }
+ kill(getpid(), SIGINT);
+}
+
+void _NXAssert(NSString* message, const char* filename, int lineNumber, const char* functionName)
+{
+ NSLog(@"***************************************************************************");
+ NSLog(@"Assertion failed at %s: %@", functionName, message);
+ NSLog(@"%s:%d", filename, lineNumber);
+ NSLog(@"***************************************************************************");
+ [NXDebug printCallStack];
+ NSLog(@"***************************************************************************");
+ _NXDebugBreak();
+}
+
+//TODO: research __attribute__ ((format (printf, 1, 2)))
+void _NXTrace(NSString* format, ...)
+{
+ va_list ap;
+
+ va_start (ap, format);
+ format = [format stringByAppendingString: @"\n"];
+ NSString* body = [[NSString alloc] initWithFormat:format arguments:ap];
+ va_end (ap);
+
+ fprintf(stderr, "%s", [body UTF8String]);
+
+ NXReleaseAndNil(body);
+}
+
+void _NXDie(NSString* reason, const char* filename, int line, const char* functionName)
+{
+ NSLog(@"Impossible situation: %@", reason);
+ NSLog(@"%s:%d:1 [%s]", filename, line, functionName);
+ [NXDebug printCallStack];
+ _NXDebugBreak();
+}
+
+
+
+@implementation NXDebug
+
++(void)printCallStack
+{
+ // callStackSymbols is available on iOS4+ only
+ if ([[NSThread class] respondsToSelector:@selector(callStackSymbols)])
+ {
+ NSArray *stack = [[NSThread class] performSelector:@selector(callStackSymbols)];
+
+ for (NSString* line in stack)
+ {
+ NSLog(@"%@", line);
+ }
+
+ }
+ else
+ {
+ NSLog(@"Stack trace unavailable");
+ }
+}
+
+@end
View
106 Frameworks/NextiveJson-20110725/NXJsonParser.h
@@ -0,0 +1,106 @@
+/*
+
+ Copyright (c) 2011 Nextive LLC
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
+ associated documentation files (the "Software"), to deal in the Software without restriction,
+ including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all copies or substantial
+ portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
+ NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
+ OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ Created by Martin Adoue (martin@nextive.com) and Hernan Pelassini (hernan@nextive.com)
+
+ */
+
+
+#import <Foundation/Foundation.h>
+#import "NXDebug.h"
+
+/// The error domain for all errors of this class.
+extern NSString* const kNextiveJsonParserErrorDomain;
+
+
+/*
+
+ TODO:
+ - Optimize the unicode escape sequence code ("\u00ae"). It works but it's slow. And ugly. And kicks puppies.
+
+ */
+/**
+
+ Implements a fast JSON parser according to the spec in http://www.json.org/
+ Also has support for C style comments.
+
+ *Note:* null values are represented as `NSNull` objects instead of nil unless ignoreNulls is YES. In that case
+ nil values are not added to dictionaries or arrays; if the JSON string is "null", nil is returned.
+
+ @warning *Important:* a malformed JSON might wrek havoc.
+
+ */
+@interface NXJsonParser : NSObject
+{
+@private
+ NSData* _data;
+ char* _bytes;
+ size_t _current;
+ size_t _length;
+
+ NSNull* _null; // Much faster than calling [NSNull null] hundreds of times.
+
+ // I keep a buffer for strings to avoid creating it and tearing it down every time.
+ char* _stringBuffer;
+ size_t _stringBufferSize;
+
+ BOOL _ignoreNulls;
+}
+
+/**
+ Encodes the jsonString to data and calls [NXJsonParser parseData:error:ignoreNulls:]
+ @param jsonString The string to parse
+ @param error The parsing error
+ @param ignoreNulls If YES null values will be ignored in the parsing process
+ @return Returns the parsed data
+ */
++(id)parseString:(NSString*)jsonString error:(NSError**)error ignoreNulls:(BOOL)ignoreNulls;
+/**
+ Parse the provided data.
+
+ @param jsonData The data to parse
+ @param error The parsing error
+ @param ignoreNulls If YES null values will be ignored in the parsing process
+ @return Returns the parsed data
+
+ */
++(id)parseData:(NSData*)jsonData error:(NSError**)error ignoreNulls:(BOOL)ignoreNulls;
+/**
+ Used to parse a specific file. Calls [NXJsonParser parseData:error:ignoreNulls:] with the given path for the file
+ @param path The file's path to parse
+ @param error The parsing error
+ @param ignoreNulls If YES null values will be ignored in the parsing process
+ @return Returns the parsed file
+ */
++(id)parseFileAtPath:(NSString*)path error:(NSError**)error ignoreNulls:(BOOL)ignoreNulls;
+/**
+ Initializes a new data object
+ @param data The data to parse
+ @return Returns the initialized data object
+ */
+-(id)initWithData:(NSData*)data NOTNULL(1);
+/**
+ Parsing of passed data occurs here
+ @param error The parsing error
+ @param ignoreNulls If YES null values will be ignored in the parsing process
+ @return Returns the parsed data
+ */
+-(id)parse:(NSError**)error ignoreNulls:(BOOL)ignoreNulls;
+
+@end
View
873 Frameworks/NextiveJson-20110725/NXJsonParser.m
@@ -0,0 +1,873 @@
+/*
+
+ Copyright (c) 2011 Nextive LLC
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
+ associated documentation files (the "Software"), to deal in the Software without restriction,
+ including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all copies or substantial
+ portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
+ NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
+ OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ Created by Martin Adoue (martin@nextive.com) and Hernan Pelassini (hernan@nextive.com)
+
+ */
+
+#import "NXJsonParser.h"
+#import "NSError+Extensions.h"
+
+NSString* const kUnexpectedCharException = @"UnexpectedCharException";
+NSString* const kUnexpectedControlCharException = @"UnexpectedControlCharException";
+NSString* const kUnexpectedEndOfFileException = @"UnexpectedEndOfFileException";
+NSString* const kUnexpectedHexCharException = @"UnexpectedHexCharException";
+
+NSString* const kNextiveJsonParserErrorDomain = @"com.nextive.NXJsonParser";
+
+@interface NXJsonParser()
+-(void)skipWhitespace;
+-(NSDictionary*)newDictionary;
+-(NSArray*)newArray;
+-(NSString*)newString;
+-(NSNumber*)newNumber;
+-(NSNumber*)newBoolean;
+-(NSNull*)newNull;
+-(id)newObject;
+
+// Deprecated. Replaced with the inline macros below.
+//-(BOOL)hasData;
+//-(char)currentChar;
+//-(char)nextChar;
+@end
+
+#define currentChar() (_bytes[_current])
+#define hasData() (_current < _length)
+#define nextChar() (_bytes[_current + 1])
+#define skip() (_current++)
+
+@implementation NXJsonParser
+
+-(void)dealloc
+{
+ NXReleaseAndNil(_data);
+ NXReleaseAndNil(_null);
+
+ free(_stringBuffer);
+
+ [super dealloc];
+}
+
++ (id)parseString:(NSString *)jsonString error:(NSError **)error ignoreNulls:(BOOL)ignoreNulls
+{
+ return [NXJsonParser parseData:[jsonString dataUsingEncoding:NSUTF8StringEncoding] error:error ignoreNulls:ignoreNulls];
+}
+
++ (id)parseData:(NSData*)jsonData error:(NSError **)error ignoreNulls:(BOOL)ignoreNulls
+{
+ NXJsonParser* parser = [[NXJsonParser alloc] initWithData:jsonData];
+ id retval = [parser parse:error ignoreNulls:ignoreNulls];
+ NXReleaseAndNil(parser);
+ return retval;
+}
+
++(id)parseFileAtPath:(NSString*)path error:(NSError**)error ignoreNulls:(BOOL)ignoreNulls
+{
+ ASSERT_CLASS(path, NSString);
+
+ NSString* string = [[NSString alloc] initWithContentsOfFile:path encoding:NSUTF8StringEncoding error:error];
+
+ if(error && *error)
+ {
+ NXReleaseAndNil(string);
+ TRACE(@"Reading JSON file failed with %@", *error);
+ return nil;
+ }
+
+ id retval = [NXJsonParser parseString:string error:error ignoreNulls:ignoreNulls];
+
+ NXReleaseAndNil(string);
+
+ return retval;
+}
+-(id)initWithData:(NSData*)data
+{
+ ASSERT(data);
+ ASSERT_CLASS(data, NSData);
+
+ if ((self = [super init]))
+ {
+ _data = [data retain];
+ _bytes = (char*)[data bytes];
+ _current = 0;
+ _length = [data length];
+ _null = [[NSNull null] retain];
+
+ _stringBufferSize = 10 * 1024;
+ _stringBuffer = (char*)malloc(_stringBufferSize * sizeof(char));
+ }
+
+ return self;
+}
+
+-(id)parse:(NSError**)error ignoreNulls:(BOOL)ignoreNulls
+{
+ _ignoreNulls = ignoreNulls;
+
+ id retval = nil;
+ @try
+ {
+ retval = [self newObject];
+ }
+ @catch (NSException* e)
+ {
+ retval = nil;
+ if(error)
+ {
+ *error = [NSError errorWithDomain:kNextiveJsonParserErrorDomain code:100 description:[e reason]];
+ }
+ }
+ @finally
+ {
+ return [retval autorelease];
+ }
+}
+
+-(id)newObject
+{
+ id retval = nil;
+
+ [self skipWhitespace];
+
+ if(hasData())
+ {
+ char c = currentChar();
+
+ switch (c)
+ {
+ case '{':
+ retval = [self newDictionary];
+ break;
+ case '[':
+ retval = [self newArray];
+ break;
+ case '\"':
+ retval = [self newString];
+ break;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ case '-':
+ case '.':
+ retval = [self newNumber];
+ break;
+ case 't':
+ case 'f':
+ retval = [self newBoolean];
+ break;
+ case 'n':
+ retval = [self newNull];
+ break;
+ case '\0':
+ [NSException raise:kUnexpectedEndOfFileException format:@"Unexpected EOF"];
+ break;
+ default:
+ [NSException raise:kUnexpectedCharException format:@"Expecting a dictionary, array, string, number, boolean, null, anything but a \"%c\"", currentChar()];
+ break;
+ }
+ }
+
+ return retval;
+}
+
+-(void)skipWhitespace
+{
+ BOOL intoComment = NO;
+ BOOL end = NO;
+ while (!end && hasData())
+ {
+ char c = currentChar();
+
+ switch (c)
+ {
+ case ' ':
+ case '\t':
+ case '\n':
+ skip();
+ break;
+ case '/':
+ if (nextChar() == '*')
+ {
+ // skip both the '/' and the '*'
+ skip();
+ skip();
+ intoComment = YES;
+ }
+ else
+ {
+ end = YES;
+ }
+ break;
+ case '*':
+ if (intoComment)
+ {
+ skip(); // skip the '*'
+ if(currentChar() == '/')
+ {
+ skip(); // skip the '/'
+ intoComment = NO;
+ }
+ }
+ else
+ {
+ end = YES;
+ }
+ break;
+ default:
+ if (intoComment)
+ {
+ skip();
+ }
+ else
+ {
+ end = YES;
+ }
+ break;
+ }
+ }
+}
+
+-(NSDictionary*)newDictionary
+{
+ ASSERT(_bytes);
+ ASSERT(hasData());
+ ASSERT(currentChar() == '{');
+
+ skip(); // skip the '{'
+
+ size_t size = 100;
+ id* keys = (id*)malloc(sizeof(id) * size);
+ ASSERT(keys);
+ id* values = (id*)malloc(sizeof(id) * size);
+ ASSERT(values);
+ NSUInteger count = 0;
+
+ @try
+ {
+ BOOL intoDictionary = YES;
+ [self skipWhitespace];
+ if(currentChar() == '}')
+ {
+ intoDictionary = NO;
+ }
+
+ while (intoDictionary)
+ {
+ [self skipWhitespace];
+
+ id key = [self newObject];
+ ASSERT(key);
+
+ [self skipWhitespace];
+
+ if(currentChar() != ':')
+ {
+ [NSException raise:kUnexpectedCharException format:@"Expecting ':', found \"%c\"", currentChar()];
+ }
+ skip();
+
+ [self skipWhitespace];
+
+ id value = [self newObject];
+
+ if (!(_ignoreNulls && !value))
+ {
+ ASSERT(value);
+
+ if (count == size)
+ {
+ size *= 2;
+ keys = (id*)realloc(keys, size * sizeof(id));
+ ASSERT(keys);
+ values = (id*)realloc(values, size * sizeof(id));
+ ASSERT(values);
+ }
+ keys[count] = key;
+ values[count] = value;
+ count++;
+ }
+
+ [self skipWhitespace];
+
+ char c = currentChar();
+ switch (c)
+ {
+ case ',':
+ // skip and keep going
+ skip();
+ break;
+ case '}':
+ intoDictionary = NO;
+ break;
+ case '\0':
+ [NSException raise:kUnexpectedEndOfFileException format:@"Unexpected EOF"];
+ break;
+ default:
+ [NSException raise:kUnexpectedCharException format:@"Expecting \",\" or \"}\", found \"%c\"", c];
+ break;
+ }
+ }
+
+ skip(); //skip the "}"
+
+ [self skipWhitespace];
+ }
+ @catch (NSException * e)
+ {
+ for (NSUInteger i = 0; i < count; i++)
+ {
+ [keys[i] release];
+ [values[i] release];
+ }
+ free(keys);
+ free(values);
+
+ [e raise];
+ }
+ @finally
+ {
+
+ // Creating a dictionary from arrays of keys and values is much much faster than adding them one item at a time.
+ NSDictionary* dict = (NSDictionary*)CFDictionaryCreate(kCFAllocatorDefault, (const void**) keys, (const void**) values, count, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+
+ for (NSUInteger i = 0; i < count; i++)
+ {
+ [keys[i] release];
+ [values[i] release];
+ }
+ free(keys);
+ free(values);
+
+ return dict;
+ }
+}
+
+-(NSNumber*)newBoolean
+{
+ ASSERT(_bytes);
+ ASSERT(hasData());
+
+ BOOL value = NO;
+
+ static char true_chars[] = {'r', 'u', 'e', '\0'};
+ static char false_chars[] = {'a', 'l', 's', 'e', '\0'};
+
+ char* array = NULL;
+ switch (currentChar())
+ {
+ case 't':
+ array = true_chars;
+ value = YES;
+ break;
+ case 'f':
+ array = false_chars;
+ value = NO;
+ break;
+ default:
+ ASSERT(!@"I should never be here. Fault the calling function.");
+ break;
+ }
+
+ ASSERT(array);
+
+ skip(); // Skip the 't' or 'f' to compare a little less. Anal retentive, me? Nah.
+
+ int pos = 0;
+ char expected = array[pos];
+
+ while (expected != '\0')
+ {
+ if (currentChar() != expected)
+ {
+ [NSException raise:kUnexpectedCharException format:@"Invalid char in a boolean: %c", currentChar()];
+ }
+ else
+ {
+ skip();
+ expected = array[++pos];
+ }
+ }
+
+ return [[NSNumber alloc] initWithBool:value];
+}
+
+-(NSNull*)newNull
+{
+ ASSERT(_bytes);
+ ASSERT(hasData());
+
+ static char expected[] = {'u', 'l', 'l', '\0'};
+
+ skip(); // skip the 'n'
+
+ int pos = 0;
+ while (expected[pos] != '\0')
+ {
+ if (currentChar() != expected[pos])
+ {
+ [NSException raise:kUnexpectedCharException format:@"Expecting '%c' (of 'null'), found %c", expected[pos], currentChar()];
+ }
+ else
+ {
+ skip();
+ pos++;
+ }
+ }
+
+ if (_ignoreNulls)
+ {
+ return nil;
+ }
+ else
+ {
+ return _null;
+ }
+
+}
+
+-(NSNumber*)newNumber
+{
+ //NOTE: this function is a mess. But it's the only way I found to make it fast.
+ ASSERT(_bytes);
+ ASSERT(hasData());
+
+ BOOL end = NO;
+ BOOL isNegative = NO;
+ BOOL hasDecimal = NO;
+ BOOL hasDigits = NO;
+ BOOL hasExponent = NO;
+ BOOL positiveExponent = NO;
+ int exponent = 0;
+
+ long long integer = 0;
+ long long decimal = 0;
+ double divisor = 10;
+
+ while(!end)
+ {
+ char c = currentChar();
+
+ switch (c)
+ {
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ hasDigits = YES;
+ if(hasDecimal)
+ {
+ decimal *= 10;
+ decimal += c - '0';
+ divisor *= 10;
+ }
+ else
+ {
+ integer *= 10;
+ integer += c - '0';
+ }
+ skip();
+ break;
+ case '-':
+ if(hasDigits)
+ {
+ [NSException raise:kUnexpectedCharException format:@"- after a digit?"];
+ }
+ if(hasDecimal)
+ {
+ [NSException raise:kUnexpectedCharException format:@"- after '.'?"];
+ }
+ if(isNegative)
+ {
+ [NSException raise:kUnexpectedCharException format:@"Two negatives one number?"];
+ }
+ isNegative = YES;
+ skip();
+ break;
+ case '.':
+ if(hasDecimal)
+ {
+ [NSException raise:kUnexpectedCharException format:@"Two decimal points one number?"];
+ }
+ hasDecimal = YES;
+ skip();
+ break;
+ case 'e':
+ case 'E':
+ if (hasExponent)
+ {
+ [NSException raise:kUnexpectedCharException format:@"Two exponents one number?"];
+ }
+ hasExponent = YES;
+ skip();
+ switch (currentChar())
+ {
+ case '+':
+ positiveExponent = YES;
+ break;
+ case '-':
+ positiveExponent = NO;
+ break;
+ default:
+ [NSException raise:kUnexpectedCharException format:@"e should be followed by '+' or '-', not '%c'", currentChar()];
+ break;
+ }
+ skip();
+ while (!end)
+ {
+ char e = currentChar();
+ if (e >= '0' && e <= '9')
+ {
+ exponent *= 10;
+ exponent += e - '0';
+ skip();
+ }
+ else
+ {
+ end = YES;
+ }
+ }
+
+
+ default:
+ end = YES;
+ break;
+ }
+ }
+
+ if(!hasDigits)
+ {
+ [NSException raise:kUnexpectedCharException format:@"No digits in a number?"];
+ }
+
+ if (hasExponent)
+ {
+ exponent = positiveExponent ? exponent : -exponent;
+ unsigned long long mantissa = (integer * divisor / 10) + decimal;
+ while (divisor > 10)
+ {
+ exponent --;
+ divisor /= 10;
+ }
+ return [[NSDecimalNumber alloc] initWithMantissa:mantissa exponent:exponent isNegative:isNegative];
+ }
+ else
+ {
+ int sign = isNegative ? -1 : 1;
+ if(hasDecimal)
+ {
+ divisor /= 10;
+ return [[NSNumber alloc] initWithDouble:sign * (integer + (decimal / divisor))];
+ }
+ else
+ {
+ return [[NSNumber alloc] initWithLongLong:sign * integer];
+ }
+ }
+
+}
+
+-(NSString*)newString
+{
+ //NOTE: this function is a mess. But it's the only way I found to make it fast.
+
+ ASSERT(_bytes);
+ ASSERT(hasData());
+ ASSERT(currentChar() == '\"');
+
+ skip(); // skip the '"'
+
+ BOOL end = NO;
+ BOOL intoEscape = NO;
+
+ size_t len = 0;
+
+#define resizeIfNeeded(newSize) \
+if(newSize > _stringBufferSize) \
+{ \
+ while(newSize > _stringBufferSize) \
+ { \
+ _stringBufferSize *= 2; \
+ } \
+ _stringBuffer = (char*)realloc(_stringBuffer, _stringBufferSize * sizeof(char)); \
+} \
+
+ while(!end)
+ {
+ char c = currentChar();
+
+ resizeIfNeeded(len);
+
+ switch (c)
+ {
+ case '\\':
+ if (intoEscape)
+ {
+ _stringBuffer[len++] = c;
+ }
+ intoEscape = !intoEscape;
+ skip();
+ break;
+ case '\"':
+ if(intoEscape)
+ {
+ intoEscape = NO;
+ skip();
+ _stringBuffer[len++] = c;
+ }
+ else
+ {
+ end = YES;
+ }
+ break;
+ case '\0':
+ [NSException raise:kUnexpectedEndOfFileException format:@"Unexpected EOF"];
+ break;
+ default:
+ if(intoEscape)
+ {
+ intoEscape = NO;
+ switch (c)
+ {
+ case '/':
+ c = '/';
+ break;
+ case 'b':
+ c = '\b';
+ break;
+ case 'f':
+ c = '\f';
+ break;
+ case 'n':
+ c = '\n';
+ break;
+ case 'r':
+ c = '\r';
+ break;
+ case 't':
+ c = '\t';
+ break;
+ case 'u':
+ skip();
+
+ unichar uc = 0;
+ for (int i = 0; i < 4; i++)
+ {
+ c = currentChar();
+ skip();
+
+ uc *= 16;
+
+ switch (c)
+ {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ uc += c - '0';
+ break;
+ case 'a':
+ case 'b':
+ case 'c':
+ case 'd':
+ case 'e':
+ case 'f':
+ uc += c - 'a' + 10;
+ break;
+ case 'A':
+ case 'B':
+ case 'C':
+ case 'D':
+ case 'E':
+ case 'F':
+ uc += c - 'A' + 10;
+ break;
+ default:
+ [NSException raise:kUnexpectedHexCharException format:@"Unexpected hex char: '\\%c'", c];
+ break;
+ }
+ }
+
+ // Ugly code
+ // The code sequence for, for example "®", is \u00ae. In UTF8 is encoded as 0xC2 0xAE.
+ // There's probably a better way to do this with some bit twiddling, but I'm tired and this works for now.
+ // Feel free to fix it.
+ NSString* utf16 = [[NSString alloc] initWithBytes:&uc length:sizeof(uc) encoding:NSASCIIStringEncoding];
+ char ubuffer[10] = {0}; // 10 is more than enough.
+ NSUInteger size = 0;
+ NSRange range = {0, 1};
+ [utf16 getBytes:&ubuffer maxLength:10 usedLength:&size encoding:NSUTF8StringEncoding options:NSStringEncodingConversionAllowLossy range:range remainingRange:NULL];
+
+ resizeIfNeeded(len + size);
+
+ for (size_t i = 0; i < size; i++)
+ {
+ _stringBuffer[len++] = ubuffer[i];
+ }
+ NXReleaseAndNil(utf16);
+
+ continue;
+
+ break;
+ default:
+ [NSException raise:kUnexpectedControlCharException format:@"Unexpected control char: '\\%c'", c];
+ break;
+ }
+ }
+
+ _stringBuffer[len++] = c;
+
+ skip();
+ break;
+ }
+ }
+
+ // The great thing about using CFStrings instead of NSStrings is that (besides it's a tiny bit faster to create)
+ // the [string copy] message simply retains it. As the string is immutable the effect is the same,
+ // only that is faster and in some cases it will use less memory.
+ NSString* retval = (NSString*)CFStringCreateWithBytes(kCFAllocatorDefault, (unsigned char*)_stringBuffer, len, kCFStringEncodingUTF8, false);
+
+ skip(); //skip the '"'
+ ASSERT(retval);
+ return retval;
+}
+
+-(NSArray*)newArray
+{
+ ASSERT(_bytes);
+ ASSERT(hasData());
+ ASSERT(currentChar() == '[');
+
+ size_t size = 100;
+ id* values = (id*)malloc(sizeof(id) * size);
+ ASSERT(values);
+ NSUInteger count = 0;
+ @try
+ {
+ skip(); // skip the '"'
+
+ BOOL intoArray = YES;
+ [self skipWhitespace];
+ if(currentChar() == ']')
+ {
+ intoArray = NO;
+ }
+ while (intoArray)
+ {
+ [self skipWhitespace];
+
+
+ id value = [self newObject];
+
+ if (!(_ignoreNulls && !value))
+ {
+ ASSERT(value);
+
+ if (count == size)
+ {
+ size *= 2;
+ values = (id*)realloc(values, size * sizeof(id));
+ ASSERT(values);
+ }
+ values[count] = value;
+ count++;
+ }
+
+ [self skipWhitespace];
+
+ char c = currentChar();
+ switch (c)
+ {
+ case ',':
+ // skip and keep going
+ skip();
+ break;
+ case ']':
+ intoArray = NO;
+ break;
+ case '\0':
+ [NSException raise:kUnexpectedEndOfFileException format:@"Unexpected EOF"];
+ break;
+ default:
+ [NSException raise:kUnexpectedCharException format:@"Expecting ',' or ']', found '%c'", c];
+ break;
+ }
+ }
+
+ skip(); //skip the "]"
+
+ [self skipWhitespace];
+ }
+ @catch (NSException * e)
+ {
+ for (NSUInteger i = 0; i < count; i++)
+ {
+ [values[i] release];
+ }
+ free(values);
+
+ [e raise];
+ }
+ @finally
+ {
+ NSArray* array = (NSArray*)CFArrayCreate(kCFAllocatorDefault, (const void**) values, count, &kCFTypeArrayCallBacks);
+ for (NSUInteger i = 0; i < count; i++)
+ {
+ [values[i] release];
+ }
+ free(values);
+
+ return array;
+ }
+
+}
+
+
+// Deprecated, replaced by the inline versions. Kept just in case we want to debug it.
+
+//-(BOOL)hasData
+//{
+// return _current < _length;
+//}
+
+//-(char)currentChar
+//{
+// ASSERT(_bytes);
+// ASSERT(_current < _length);
+// return _bytes[_current];
+//}
+
+//-(char)nextChar
+//{
+// ASSERT(_bytes);
+// ASSERT(_current + 1 < _length);
+// return _bytes[_current + 1];
+//}
+
+@end
View
83 Frameworks/NextiveJson-20110725/NXJsonSerializer.h
@@ -0,0 +1,83 @@
+/*
+
+ Copyright (c) 2011 Nextive LLC
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
+ associated documentation files (the "Software"), to deal in the Software without restriction,
+ including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all copies or substantial
+ portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
+ NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
+ OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ Created by Martin Adoue (martin@nextive.com) and Hernan Pelassini (hernan@nextive.com)
+
+ */
+
+
+
+#import <Foundation/Foundation.h>
+
+/**
+
+ Serializes an object structure to Json, according to the spec in http://www.json.org/
+
+ Supports NSDictionary, NSArray, NSString, NSNumber, NSNull and its subclasses.
+ If you implement the NXSerializable protocol, just serialize yourself to a dictionary
+ (or array, or any JSON compatible type) and we'll do our best.
+
+ @warning *Important*: Do NOT try to serialize a recursive structure.
+
+ */
+@interface NXJsonSerializer : NSObject
+{
+@private
+ // We keep references to [XX class] here for performance reasons. Yes. Really. Calling
+ // [XX class] thousands of times is expensive.
+ Class _nullClass;
+ Class _dictClass;
+ Class _arraClass;
+ Class _numbClass;
+ Class _striClass;
+
+ Class _nullClassCached;
+ Class _dictClassCached;
+ Class _arraClassCached;
+ Class _numbClassCached;
+ Class _striClassCached;
+
+ char* _buffer;
+ size_t _length;
+ size_t _current;