-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
27 changed files
with
2,194 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
7 changes: 7 additions & 0 deletions
7
JSONTools.xcodeproj/project.xcworkspace/contents.xcworkspacedata
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
69 changes: 69 additions & 0 deletions
69
JSONTools.xcodeproj/xcuserdata/greg.xcuserdatad/xcschemes/JSONTools.xcscheme
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<Scheme | ||
LastUpgradeVersion = "0510" | ||
version = "1.3"> | ||
<BuildAction | ||
parallelizeBuildables = "YES" | ||
buildImplicitDependencies = "YES"> | ||
<BuildActionEntries> | ||
<BuildActionEntry | ||
buildForTesting = "YES" | ||
buildForRunning = "YES" | ||
buildForProfiling = "YES" | ||
buildForArchiving = "YES" | ||
buildForAnalyzing = "YES"> | ||
<BuildableReference | ||
BuildableIdentifier = "primary" | ||
BlueprintIdentifier = "37BDF4BC18FAF1DD00BF9705" | ||
BuildableName = "libJSONTools.a" | ||
BlueprintName = "JSONTools" | ||
ReferencedContainer = "container:JSONTools.xcodeproj"> | ||
</BuildableReference> | ||
</BuildActionEntry> | ||
</BuildActionEntries> | ||
</BuildAction> | ||
<TestAction | ||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" | ||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" | ||
shouldUseLaunchSchemeArgsEnv = "YES" | ||
buildConfiguration = "Debug"> | ||
<Testables> | ||
<TestableReference | ||
skipped = "NO"> | ||
<BuildableReference | ||
BuildableIdentifier = "primary" | ||
BlueprintIdentifier = "37BDF4CC18FAF1DD00BF9705" | ||
BuildableName = "JSONToolsTests.xctest" | ||
BlueprintName = "JSONToolsTests" | ||
ReferencedContainer = "container:JSONTools.xcodeproj"> | ||
</BuildableReference> | ||
</TestableReference> | ||
</Testables> | ||
</TestAction> | ||
<LaunchAction | ||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" | ||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" | ||
launchStyle = "0" | ||
useCustomWorkingDirectory = "NO" | ||
buildConfiguration = "Debug" | ||
ignoresPersistentStateOnLaunch = "NO" | ||
debugDocumentVersioning = "YES" | ||
allowLocationSimulation = "YES"> | ||
<AdditionalOptions> | ||
</AdditionalOptions> | ||
</LaunchAction> | ||
<ProfileAction | ||
shouldUseLaunchSchemeArgsEnv = "YES" | ||
savedToolIdentifier = "" | ||
useCustomWorkingDirectory = "NO" | ||
buildConfiguration = "Release" | ||
debugDocumentVersioning = "YES"> | ||
</ProfileAction> | ||
<AnalyzeAction | ||
buildConfiguration = "Debug"> | ||
</AnalyzeAction> | ||
<ArchiveAction | ||
buildConfiguration = "Release" | ||
revealArchiveInOrganizer = "YES"> | ||
</ArchiveAction> | ||
</Scheme> |
27 changes: 27 additions & 0 deletions
27
JSONTools.xcodeproj/xcuserdata/greg.xcuserdatad/xcschemes/xcschememanagement.plist
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | ||
<plist version="1.0"> | ||
<dict> | ||
<key>SchemeUserState</key> | ||
<dict> | ||
<key>JSONTools.xcscheme</key> | ||
<dict> | ||
<key>orderHint</key> | ||
<integer>0</integer> | ||
</dict> | ||
</dict> | ||
<key>SuppressBuildableAutocreation</key> | ||
<dict> | ||
<key>37BDF4BC18FAF1DD00BF9705</key> | ||
<dict> | ||
<key>primary</key> | ||
<true/> | ||
</dict> | ||
<key>37BDF4CC18FAF1DD00BF9705</key> | ||
<dict> | ||
<key>primary</key> | ||
<true/> | ||
</dict> | ||
</dict> | ||
</dict> | ||
</plist> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
// | ||
// JSONPatch.h | ||
// inspired by https://github.com/Starcounter-Jack/JSON-Patch | ||
// | ||
// JSONTools | ||
// | ||
// Copyright (C) 2014 Gregory Combs [gcombs at gmail] | ||
// See LICENSE.txt for details. | ||
|
||
#import "JSONTools.h" | ||
|
||
@interface JSONPatch : NSObject | ||
|
||
/** | ||
* Implements IETF RFC6902 - JSON Patch | ||
* @see https://tools.ietf.org/html/rfc6902 | ||
* | ||
* @param patches An array of one or more patch dictionaries in the form of: | ||
* `{"op":"add", "path": "/foo/0/bar", "value": "thing"}` | ||
* - `op` is one of: "add", "remove", "copy", "move", "test", "_get" | ||
* - `path` is a JSON Pointer (RFC 6901) (see JSONPointer.h) | ||
* - `value` is an objective-c object ( | ||
* | ||
* @param collection A ***mutable*** dictionary or ***mutable*** array to patch | ||
* | ||
* @return For all but "_get", the result is an NSNumber boolean indicating patch success. | ||
* However, for "_get" operations, the result will be the collection's content | ||
* corresponding to the supplied patch JSON Pointer (i.e. "path") | ||
*/ | ||
+ (id)applyPatches:(NSArray *)patches toCollection:(id)collection; | ||
|
||
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,179 @@ | ||
// | ||
// JSONPatch.m | ||
// inspired by https://github.com/Starcounter-Jack/JSON-Patch | ||
// | ||
// JSONTools | ||
// | ||
// Copyright (C) 2014 Gregory Combs [gcombs at gmail] | ||
// See LICENSE.txt for details. | ||
|
||
#import "JSONPatch.h" | ||
#import "JSONPatchDictionary.h" | ||
#import "JSONPatchArray.h" | ||
#import "JSONPointer.h" | ||
|
||
@implementation JSONPatch | ||
|
||
+ (id)applyPatches:(NSArray *)patches toCollection:(id)collection | ||
{ | ||
if (!collection || | ||
![collection respondsToSelector:@selector(mutableCopy)]) | ||
{ | ||
return nil; | ||
} | ||
|
||
id result = nil; | ||
|
||
for (NSDictionary *patch in patches) | ||
{ | ||
JSONPatchInfo *patchInfo = [JSONPatchInfo newPatchInfoWithDictionary:patch]; | ||
if (!patchInfo) | ||
break; | ||
|
||
NSArray *pathKeys = [patchInfo.path componentsSeparatedByString:@"/"]; | ||
id object = collection; | ||
NSInteger t = 1; | ||
|
||
while (YES) { | ||
if (![object isKindOfClass:[NSMutableDictionary class]] && | ||
![object isKindOfClass:[NSMutableArray class]] && | ||
[object respondsToSelector:@selector(mutableCopy)]) | ||
{ | ||
object = [object mutableCopy]; | ||
} | ||
|
||
if ([object isKindOfClass:[NSMutableArray class]]) | ||
{ | ||
NSString *component = pathKeys[t]; | ||
NSInteger index = [(NSMutableArray *)object indexForJSONPointerComponent:component]; | ||
if (index == NSNotFound) | ||
break; | ||
|
||
t++; | ||
|
||
if (t >= pathKeys.count) | ||
{ | ||
BOOL stop = NO; | ||
result = [self applyPatch:patchInfo array:object index:index collection:collection stop:&stop]; | ||
if (stop) { | ||
return result; | ||
} | ||
break; | ||
} | ||
object = (NSMutableArray *)object[index]; | ||
} | ||
else if ([object isKindOfClass:[NSMutableDictionary class]]) | ||
{ | ||
NSString *component = [(NSMutableDictionary *)object keyForJSONPointerComponent:pathKeys[t]]; | ||
|
||
t++; | ||
|
||
if (t >= pathKeys.count) | ||
{ | ||
BOOL stop = NO; | ||
result = [self applyPatch:patchInfo dictionary:object key:component collection:collection stop:&stop]; | ||
if (stop) { | ||
return result; | ||
} | ||
break; | ||
} | ||
object = (NSMutableDictionary *)object[component]; | ||
} | ||
} | ||
} | ||
return result; | ||
} | ||
|
||
#pragma mark - Singular Patch | ||
|
||
+ (id)applyPatch:(JSONPatchInfo *)patchInfo array:(NSMutableArray *)array index:(NSInteger)index collection:(id)collection stop:(BOOL *)stop | ||
{ | ||
BOOL success = NO; | ||
switch (patchInfo.op) | ||
{ | ||
case JSONPatchOperationGet: | ||
case JSONPatchOperationTest: | ||
*stop = YES; | ||
return [JSONPatchArray applyPatchInfo:patchInfo object:array index:index]; | ||
break; | ||
case JSONPatchOperationAdd: | ||
case JSONPatchOperationReplace: | ||
case JSONPatchOperationRemove: | ||
success = ([[JSONPatchArray applyPatchInfo:patchInfo object:array index:index] boolValue]); | ||
break; | ||
case JSONPatchOperationCopy: | ||
success = [self applyCopyPatch:patchInfo toCollection:collection]; | ||
break; | ||
case JSONPatchOperationMove: | ||
success = [self applyMovePatch:patchInfo toCollection:collection]; | ||
break; | ||
case JSONPatchOperationUndefined: | ||
break; | ||
} | ||
if (!success) | ||
return nil; | ||
return @(success); | ||
} | ||
|
||
+ (id)applyPatch:(JSONPatchInfo *)patchInfo dictionary:(NSMutableDictionary *)dictionary key:(NSString *)key collection:(id)collection stop:(BOOL *)stop | ||
{ | ||
BOOL success = NO; | ||
switch (patchInfo.op) | ||
{ | ||
case JSONPatchOperationGet: | ||
case JSONPatchOperationTest: | ||
*stop = YES; | ||
return [JSONPatchDictionary applyPatchInfo:patchInfo object:dictionary key:key]; | ||
break; | ||
case JSONPatchOperationAdd: | ||
case JSONPatchOperationReplace: | ||
case JSONPatchOperationRemove: | ||
success = ([[JSONPatchDictionary applyPatchInfo:patchInfo object:dictionary key:key] boolValue]); | ||
break; | ||
case JSONPatchOperationCopy: | ||
success = [self applyCopyPatch:patchInfo toCollection:collection]; | ||
break; | ||
case JSONPatchOperationMove: | ||
success = [self applyMovePatch:patchInfo toCollection:collection]; | ||
break; | ||
case JSONPatchOperationUndefined: | ||
break; | ||
} | ||
if (!success) | ||
return nil; | ||
return @(success); | ||
} | ||
|
||
#pragma mark - Aggregated Operations | ||
|
||
+ (BOOL)applyCopyPatch:(JSONPatchInfo *)patchInfo toCollection:(id)collection | ||
{ | ||
id fromValue = [self applyPatches:@[@{@"op": @"_get", | ||
@"path": patchInfo.fromPath}] toCollection:collection]; | ||
if (!fromValue) { | ||
return NO; | ||
} | ||
id toResult = [self applyPatches:@[@{@"op": @"add", | ||
@"path": patchInfo.path, | ||
@"value": fromValue}] toCollection:collection]; | ||
return (toResult != NULL); | ||
} | ||
|
||
+ (BOOL)applyMovePatch:(JSONPatchInfo *)patchInfo toCollection:(id)collection | ||
{ | ||
id fromValue = [self applyPatches:@[@{@"op": @"_get", | ||
@"path": patchInfo.fromPath}] toCollection:collection]; | ||
if (!fromValue) | ||
{ | ||
return NO; | ||
} | ||
id removeResult = [self applyPatches:@[@{@"op": @"remove", | ||
@"path": patchInfo.fromPath}] toCollection:collection]; | ||
id toResult = [self applyPatches:@[@{@"op": @"add", | ||
@"path": patchInfo.path, | ||
@"value": fromValue}] toCollection:collection]; | ||
return (toResult != NULL && | ||
removeResult != NULL); | ||
} | ||
|
||
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
// | ||
// JSONPatchArray.h | ||
// inspired by https://github.com/Starcounter-Jack/JSON-Patch | ||
// | ||
// JSONTools | ||
// | ||
// Copyright (C) 2014 Gregory Combs [gcombs at gmail] | ||
// See LICENSE.txt for details. | ||
|
||
#import "JSONTools.h" | ||
#import "JSONPatchInfo.h" | ||
|
||
@interface JSONPatchArray: NSObject | ||
+ (id)applyPatchInfo:(JSONPatchInfo *)info object:(NSMutableArray *)object index:(NSInteger)index; | ||
@end |
Oops, something went wrong.