Clean up root folder.
[enjoyable.git] / Classes / NJMapping.m
diff --git a/Classes/NJMapping.m b/Classes/NJMapping.m
new file mode 100644 (file)
index 0000000..8cc5724
--- /dev/null
@@ -0,0 +1,91 @@
+//
+//  NJMapping.m
+//  Enjoy
+//
+//  Created by Sam McCall on 4/05/09.
+//
+
+#import "NJMapping.h"
+
+#import "NJInput.h"
+#import "NJOutput.h"
+
+@implementation NJMapping
+
+- (id)initWithName:(NSString *)name {
+    if ((self = [super init])) {
+        self.name = name ? name : @"Untitled";
+        _entries = [[NSMutableDictionary alloc] init];
+    }
+    return self;
+}
+
+- (NJOutput *)objectForKeyedSubscript:(NJInput *)input {
+    return input ? _entries[input.uid] : nil;
+}
+
+- (void)setObject:(NJOutput *)output forKeyedSubscript:(NJInput *)input {
+    if (input) {
+        if (output)
+            _entries[input.uid] = output;
+        else
+            [_entries removeObjectForKey:input.uid];
+    }
+}
+
+- (NSDictionary *)serialize {
+    NSMutableDictionary *entries = [[NSMutableDictionary alloc] initWithCapacity:_entries.count];
+    for (id key in _entries) {
+        id serialized = [_entries[key] serialize];
+        if (serialized)
+            entries[key] = serialized;
+    }
+    return @{ @"name": _name, @"entries": entries };
+}
+
+- (BOOL)writeToURL:(NSURL *)url error:(NSError **)error {
+    [NSProcessInfo.processInfo disableSuddenTermination];
+    NSDictionary *serialization = [self serialize];
+    NSData *json = [NSJSONSerialization dataWithJSONObject:serialization
+                                                   options:NSJSONWritingPrettyPrinted
+                                                     error:error];
+    BOOL success = json && [json writeToURL:url options:NSDataWritingAtomic error:error];
+    [NSProcessInfo.processInfo enableSuddenTermination];
+    return success;
+}
+
++ (id)mappingWithContentsOfURL:(NSURL *)url mappings:(NSArray *)mappings error:(NSError **)error {
+    NSInputStream *stream = [NSInputStream inputStreamWithURL:url];
+    [stream open];
+    NSDictionary *serialization = stream && !*error
+        ? [NSJSONSerialization JSONObjectWithStream:stream options:0 error:error]
+        : nil;
+    [stream close];
+    
+    if (!serialization && error)
+        return nil;
+    
+    if (!([serialization isKindOfClass:NSDictionary.class]
+          && [serialization[@"name"] isKindOfClass:NSString.class]
+          && [serialization[@"entries"] isKindOfClass:NSDictionary.class])) {
+        *error = [NSError errorWithDomain:@"Enjoyable"
+                                     code:0
+                              description:@"This isn't a valid mapping file."];
+        return nil;
+    }
+    
+    NSDictionary *entries = serialization[@"entries"];
+    NJMapping *mapping = [[NJMapping alloc] initWithName:serialization[@"name"]];
+    for (id key in entries) {
+        NSDictionary *value = entries[key];
+        if ([key isKindOfClass:NSString.class]) {
+            NJOutput *output = [NJOutput outputDeserialize:value
+                                              withMappings:mappings];
+            if (output)
+                mapping.entries[key] = output;
+        }
+    }
+    return mapping;
+}
+
+@end