Permalink
Browse files

Added DTASN1Serialization class

  • Loading branch information...
1 parent 26f69eb commit 1328a20d5aa69e840b58ad003b01753189d481f3 @odrobnik odrobnik committed Mar 9, 2013
View
17 Core/Source/DTASN1Parser.h
@@ -36,6 +36,7 @@ typedef enum
DTASN1TypeGeneralString = 0x1b,
DTASN1TypeUniversalString = 0x1c,
DTASN1TypeBitmapString = 0x1e,
+ DTASN1TypeUsesLongForm = 0x1f
} DTASN1Type;
@@ -78,6 +79,22 @@ typedef enum
- (void)parser:(DTASN1Parser *)parser didEndContainerWithType:(DTASN1Type)type;
/**
+ Sent by a parser object to its delegate when it encounters the beginning of a context-specific tag.
+
+ @param parser A parser object.
+ @param tag The tag value for the context that contains the subsequent elements.
+ */
+- (void)parser:(DTASN1Parser *)parser didStartContextWithTag:(NSUInteger)tag;
+
+/**
+ Sent by a parser object to its delegate when it encounters the end of a constructed element.
+
+ @param parser A parser object.
+ @param tag The tag value for the context that contained the previous elements.
+ */
+- (void)parser:(DTASN1Parser *)parser didEndContextWithTag:(NSUInteger)tag;
+
+/**
Sent by a parser object to its delegate when it encounters a fatal error.
When this method is invoked, parsing is stopped. For further information about the error, you can query parseError or you can send the parser a parserError message. You can also send the parser lineNumber and columnNumber messages to further isolate where the error occurred. Typically you implement this method to display information about the error to the user.
View
47 Core/Source/DTASN1Parser.m
@@ -26,6 +26,8 @@ @implementation DTASN1Parser
unsigned int delegateSupportsDocumentEnd:1;
unsigned int delegateSupportsContainerStart:1;
unsigned int delegateSupportsContainerEnd:1;
+ unsigned int delegateSupportsContextStart:1;
+ unsigned int delegateSupportsContextEnd:1;
unsigned int delegateSupportsString:1;
unsigned int delegateSupportsInteger:1;
unsigned int delegateSupportsData:1;
@@ -385,11 +387,11 @@ - (BOOL)_parseRange:(NSRange)range
// BOOL isSeq = tagByte & 32;
// BOOL isContext = tagByte & 128;
- //NSUInteger tagClass = tagByte >> 6;
+ NSUInteger tagClass = tagByte >> 6;
DTASN1Type tagType = tagByte & 31;
BOOL tagConstructed = (tagByte >> 5) & 1;
- if (tagType == 0x1f)
+ if (tagType == DTASN1TypeUsesLongForm)
{
[self _parseErrorEncountered:@"Long form not implemented"];
return NO;
@@ -410,9 +412,32 @@ - (BOOL)_parseRange:(NSRange)range
// make range
NSRange subRange = NSMakeRange(location, length);
+ if (NSMaxRange(subRange) > NSMaxRange(range))
+ {
+ return NO;
+ }
+
+ if (tagClass == 2)
+ {
+ if (_delegateFlags.delegateSupportsContextStart)
+ {
+ [_delegate parser:self didStartContextWithTag:tagType];
+ }
+
+ if (!tagConstructed)
+ {
+ tagType = DTASN1TypeOctetString;
+ }
+ }
+
if (tagConstructed)
{
// constructed element
+ if (subRange.length == 0)
+ {
+ return NO;
+ }
+
if (_delegateFlags.delegateSupportsContainerStart)
{
@@ -438,6 +463,14 @@ - (BOOL)_parseRange:(NSRange)range
}
}
+ if (tagClass == 2)
+ {
+ if (_delegateFlags.delegateSupportsContextStart)
+ {
+ [_delegate parser:self didEndContextWithTag:tagType];
+ }
+ }
+
// advance
location += length;
@@ -511,6 +544,16 @@ - (void)setDelegate:(__unsafe_unretained id<DTASN1ParserDelegate>)delegate;
_delegateFlags.delegateSupportsContainerEnd= YES;
}
+ if ([_delegate respondsToSelector:@selector(parser:didStartContextWithTag:)])
+ {
+ _delegateFlags.delegateSupportsContextStart = YES;
+ }
+
+ if ([_delegate respondsToSelector:@selector(parser:didEndContextWithTag:)])
+ {
+ _delegateFlags.delegateSupportsContextEnd = YES;
+ }
+
if ([_delegate respondsToSelector:@selector(parser:parseErrorOccurred:)])
{
_delegateFlags.delegateSupportsError = YES;
View
15 Core/Source/DTASN1Serialization.h
@@ -0,0 +1,15 @@
+//
+// DTASN1Serialization.h
+// DTFoundation
+//
+// Created by Oliver Drobnik on 3/9/13.
+// Copyright (c) 2013 Cocoanetics. All rights reserved.
+//
+
+#import "DTASN1Parser.h"
+
+@interface DTASN1Serialization : NSObject
+
++ (id)objectWithData:(NSData *)data;
+
+@end
View
148 Core/Source/DTASN1Serialization.m
@@ -0,0 +1,148 @@
+//
+// DTASN1Serialization.m
+// DTFoundation
+//
+// Created by Oliver Drobnik on 3/9/13.
+// Copyright (c) 2013 Cocoanetics. All rights reserved.
+//
+
+#import "DTASN1Serialization.h"
+#import "DTASN1Parser.h"
+#import "DTBase64Coding.h"
+
+@interface DTASN1Serialization () <DTASN1ParserDelegate>
+
+@property (nonatomic, readonly) id rootObject;
+
+- (id)initWithData:(NSData *)data;
+
+@end
+
+@implementation DTASN1Serialization
+{
+ id _rootObject;
+ id _currentContainer;
+ NSMutableArray *_stack;
+}
+
++ (id)objectWithData:(NSData *)data
+{
+ DTASN1Serialization *decoder = [[DTASN1Serialization alloc] initWithData:data];
+
+ return decoder.rootObject;
+}
+
+
+// private initializer
+- (id)initWithData:(NSData *)data
+{
+ self = [super init];
+
+ NSString *bas = [DTBase64Coding stringByEncodingData:data];
+ NSLog(@"%@", bas);
+
+ if (self)
+ {
+ DTASN1Parser *parser = [[DTASN1Parser alloc] initWithData:data];
+ parser.delegate = self;
+
+ if (![parser parse])
+ {
+ return nil;
+ }
+ }
+ return self;
+}
+
+- (void)_pushContainer:(id)container
+{
+ if (!_stack)
+ {
+ _stack = [NSMutableArray array];
+ _rootObject = container;
+ }
+
+ [_currentContainer addObject:container];
+
+ [_stack addObject:container];
+ _currentContainer = container;
+}
+
+- (void)_addObjectToCurrentContainer:(id)object
+{
+ if (!_stack)
+ {
+ _stack = [NSMutableArray array];
+ _rootObject = object;
+ }
+
+ [_currentContainer addObject:object];
+}
+
+- (void)_popContainer
+{
+ [_stack removeLastObject];
+ _currentContainer = [_stack lastObject];
+}
+
+#pragma mark - DTASN1 Parser Delegate
+
+- (void)parser:(DTASN1Parser *)parser didStartContainerWithType:(DTASN1Type)type
+{
+ NSMutableArray *newContainer = [NSMutableArray array];
+ [self _pushContainer:newContainer];
+}
+
+- (void)parser:(DTASN1Parser *)parser didEndContainerWithType:(DTASN1Type)type
+{
+ [self _popContainer];
+}
+
+- (void)parser:(DTASN1Parser *)parser didStartContextWithTag:(NSUInteger)tag constructed:(BOOL)constructed
+{
+ NSNumber *tagNumber = [NSNumber numberWithUnsignedInteger:tag];
+
+ NSMutableArray *newContainer = [NSMutableArray array];
+ NSDictionary *dictionary = [NSDictionary dictionaryWithObject:newContainer forKey:tagNumber];
+
+ [self _pushContainer:dictionary];
+ _currentContainer = newContainer;
+}
+
+- (void)parser:(DTASN1Parser *)parser didEndContextWithTag:(NSUInteger)tag constructed:(BOOL)constructed
+{
+ [self _popContainer];
+}
+
+- (void)parserFoundNull:(DTASN1Parser *)parser
+{
+ [self _addObjectToCurrentContainer:[NSNull null]];
+}
+
+- (void)parser:(DTASN1Parser *)parser foundDate:(NSDate *)date
+{
+ [self _addObjectToCurrentContainer:date];
+}
+
+- (void)parser:(DTASN1Parser *)parser foundObjectIdentifier:(NSString *)objIdentifier
+{
+ [self _addObjectToCurrentContainer:objIdentifier];
+}
+
+- (void)parser:(DTASN1Parser *)parser foundString:(NSString *)string
+{
+ [self _addObjectToCurrentContainer:string];
+}
+
+- (void)parser:(DTASN1Parser *)parser foundData:(NSData *)data
+{
+ [self _addObjectToCurrentContainer:data];
+}
+
+- (void)parser:(DTASN1Parser *)parser foundNumber:(NSNumber *)number
+{
+ [self _addObjectToCurrentContainer:number];
+}
+
+
+@end
View
22 DTFoundation.xcodeproj/project.pbxproj
@@ -169,6 +169,13 @@
A777831316CA47F60048BED1 /* DTObjectBlockExecutor.m in Sources */ = {isa = PBXBuildFile; fileRef = A777830E16CA47F60048BED1 /* DTObjectBlockExecutor.m */; };
A777831416CA47F60048BED1 /* DTObjectBlockExecutor.m in Sources */ = {isa = PBXBuildFile; fileRef = A777830E16CA47F60048BED1 /* DTObjectBlockExecutor.m */; };
A777831516CA49C80048BED1 /* NSObject+DTRuntime.m in Sources */ = {isa = PBXBuildFile; fileRef = A7FE30671548009A00F5DC66 /* NSObject+DTRuntime.m */; };
+ A779A38416EB850D001BD056 /* DTASN1Serialization.h in Headers */ = {isa = PBXBuildFile; fileRef = A779A38216EB850D001BD056 /* DTASN1Serialization.h */; };
+ A779A38516EB850D001BD056 /* DTASN1Serialization.h in Headers */ = {isa = PBXBuildFile; fileRef = A779A38216EB850D001BD056 /* DTASN1Serialization.h */; };
+ A779A38616EB850D001BD056 /* DTASN1Serialization.h in Headers */ = {isa = PBXBuildFile; fileRef = A779A38216EB850D001BD056 /* DTASN1Serialization.h */; };
+ A779A38716EB850D001BD056 /* DTASN1Serialization.m in Sources */ = {isa = PBXBuildFile; fileRef = A779A38316EB850D001BD056 /* DTASN1Serialization.m */; };
+ A779A38816EB850D001BD056 /* DTASN1Serialization.m in Sources */ = {isa = PBXBuildFile; fileRef = A779A38316EB850D001BD056 /* DTASN1Serialization.m */; };
+ A779A38916EB850D001BD056 /* DTASN1Serialization.m in Sources */ = {isa = PBXBuildFile; fileRef = A779A38316EB850D001BD056 /* DTASN1Serialization.m */; };
+ A779A38C16EB8BFB001BD056 /* DTASN1SerializationTest.m in Sources */ = {isa = PBXBuildFile; fileRef = A779A38B16EB8BFB001BD056 /* DTASN1SerializationTest.m */; };
A77D5BFA16E4961A00A45C28 /* DTBase64Coding.h in Headers */ = {isa = PBXBuildFile; fileRef = A77D5BF816E4961A00A45C28 /* DTBase64Coding.h */; };
A77D5BFB16E4961A00A45C28 /* DTBase64Coding.h in Headers */ = {isa = PBXBuildFile; fileRef = A77D5BF816E4961A00A45C28 /* DTBase64Coding.h */; };
A77D5BFC16E4961A00A45C28 /* DTBase64Coding.h in Headers */ = {isa = PBXBuildFile; fileRef = A77D5BF816E4961A00A45C28 /* DTBase64Coding.h */; };
@@ -441,6 +448,10 @@
A76DB4FA16A5E5950010CD85 /* NSString+DTUTI.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+DTUTI.m"; sourceTree = "<group>"; };
A777830D16CA47F60048BED1 /* DTObjectBlockExecutor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DTObjectBlockExecutor.h; sourceTree = "<group>"; };
A777830E16CA47F60048BED1 /* DTObjectBlockExecutor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DTObjectBlockExecutor.m; sourceTree = "<group>"; };
+ A779A38216EB850D001BD056 /* DTASN1Serialization.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DTASN1Serialization.h; sourceTree = "<group>"; };
+ A779A38316EB850D001BD056 /* DTASN1Serialization.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DTASN1Serialization.m; sourceTree = "<group>"; };
+ A779A38A16EB8BFB001BD056 /* DTASN1SerializationTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DTASN1SerializationTest.h; sourceTree = "<group>"; };
+ A779A38B16EB8BFB001BD056 /* DTASN1SerializationTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DTASN1SerializationTest.m; sourceTree = "<group>"; };
A77D5BF816E4961A00A45C28 /* DTBase64Coding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DTBase64Coding.h; sourceTree = "<group>"; };
A77D5BF916E4961A00A45C28 /* DTBase64Coding.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DTBase64Coding.m; sourceTree = "<group>"; };
A77D5C0016E4B1D300A45C28 /* DTBase64CodingTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DTBase64CodingTest.h; sourceTree = "<group>"; };
@@ -853,6 +864,8 @@
A7556F63162EEF6700A69F63 /* DTScripting */,
A760F52A14F24B9F00AD1B0E /* DTASN1Parser.h */,
A760F52B14F24B9F00AD1B0E /* DTASN1Parser.m */,
+ A779A38216EB850D001BD056 /* DTASN1Serialization.h */,
+ A779A38316EB850D001BD056 /* DTASN1Serialization.m */,
A7D6F2E315063448001CACDD /* DTExtendedFileAttributes.h */,
A7D6F2E415063448001CACDD /* DTExtendedFileAttributes.m */,
A70B4CC71486621B00873A4A /* DTVersion.h */,
@@ -893,6 +906,8 @@
C04947C63C389A913634F6A8 /* DTZipArchiveTest.h */,
A77D5C0016E4B1D300A45C28 /* DTBase64CodingTest.h */,
A77D5C0116E4B1D300A45C28 /* DTBase64CodingTest.m */,
+ A779A38A16EB8BFB001BD056 /* DTASN1SerializationTest.h */,
+ A779A38B16EB8BFB001BD056 /* DTASN1SerializationTest.m */,
);
path = Source;
sourceTree = "<group>";
@@ -1017,6 +1032,7 @@
A70ECD6716E0A06E004E9623 /* DTStripedLayerTile.h in Headers */,
A70ECD6D16E0A389004E9623 /* UIColor+DTDebug.h in Headers */,
A77D5BFB16E4961A00A45C28 /* DTBase64Coding.h in Headers */,
+ A779A38516EB850D001BD056 /* DTASN1Serialization.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -1041,6 +1057,7 @@
A76DB4F616A5E5590010CD85 /* NSWindowController+DTPanelControllerPresenting.h in Headers */,
A777831116CA47F60048BED1 /* DTObjectBlockExecutor.h in Headers */,
A77D5BFC16E4961A00A45C28 /* DTBase64Coding.h in Headers */,
+ A779A38616EB850D001BD056 /* DTASN1Serialization.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -1094,6 +1111,7 @@
A70ECD6616E0A06E004E9623 /* DTStripedLayerTile.h in Headers */,
A70ECD6C16E0A389004E9623 /* UIColor+DTDebug.h in Headers */,
A77D5BFA16E4961A00A45C28 /* DTBase64Coding.h in Headers */,
+ A779A38416EB850D001BD056 /* DTASN1Serialization.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -1442,6 +1460,7 @@
A70ECD6916E0A06E004E9623 /* DTStripedLayerTile.m in Sources */,
A70ECD6F16E0A389004E9623 /* UIColor+DTDebug.m in Sources */,
A77D5BFE16E4961A00A45C28 /* DTBase64Coding.m in Sources */,
+ A779A38816EB850D001BD056 /* DTASN1Serialization.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -1474,6 +1493,7 @@
A777831416CA47F60048BED1 /* DTObjectBlockExecutor.m in Sources */,
A777831516CA49C80048BED1 /* NSObject+DTRuntime.m in Sources */,
A77D5BFF16E4961A00A45C28 /* DTBase64Coding.m in Sources */,
+ A779A38916EB850D001BD056 /* DTASN1Serialization.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -1528,6 +1548,7 @@
A70ECD6816E0A06E004E9623 /* DTStripedLayerTile.m in Sources */,
A70ECD6E16E0A389004E9623 /* UIColor+DTDebug.m in Sources */,
A77D5BFD16E4961A00A45C28 /* DTBase64Coding.m in Sources */,
+ A779A38716EB850D001BD056 /* DTASN1Serialization.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -1542,6 +1563,7 @@
A70D56A6162FDECF00120A98 /* DTScriptingTest.m in Sources */,
A77D5C0216E4B1D300A45C28 /* DTBase64CodingTest.m in Sources */,
FA08F96016E4EEAF00BDF822 /* DTZipArchiveTest.m in Sources */,
+ A779A38C16EB8BFB001BD056 /* DTASN1SerializationTest.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
View
13 Test/Source/DTASN1SerializationTest.h
@@ -0,0 +1,13 @@
+//
+// DTASN1SerializationTest.h
+// DTFoundation
+//
+// Created by Oliver Drobnik on 3/9/13.
+// Copyright (c) 2013 Cocoanetics. All rights reserved.
+//
+
+#import <SenTestingKit/SenTestingKit.h>
+
+@interface DTASN1SerializationTest : SenTestCase
+
+@end
View
25 Test/Source/DTASN1SerializationTest.m
@@ -0,0 +1,25 @@
+//
+// DTASN1SerializationTest.m
+// DTFoundation
+//
+// Created by Oliver Drobnik on 3/9/13.
+// Copyright (c) 2013 Cocoanetics. All rights reserved.
+//
+
+#import "DTASN1SerializationTest.h"
+
+#import "DTASN1Serialization.h"
+#import "DTBase64Coding.h"
+
+@implementation DTASN1SerializationTest
+
+- (void)testDeserialization
+{
+ NSString *string = @"MBaAFDxB4o8ICKlMJYmNbcU40PyFjGIX";
+ NSData *data = [DTBase64Coding dataByDecodingString:string];
+
+ id object = [DTASN1Serialization objectWithData:data];
+ NSLog(@"%@", object);
+}
+
+@end

0 comments on commit 1328a20

Please sign in to comment.