Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Added DTASN1Serialization class

  • Loading branch information...
commit 1328a20d5aa69e840b58ad003b01753189d481f3 1 parent 26f69eb
Oliver Drobnik authored
17 Core/Source/DTASN1Parser.h
View
@@ -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.
47 Core/Source/DTASN1Parser.m
View
@@ -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;
15 Core/Source/DTASN1Serialization.h
View
@@ -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
148 Core/Source/DTASN1Serialization.m
View
@@ -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
22 DTFoundation.xcodeproj/project.pbxproj
View
@@ -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;
};
13 Test/Source/DTASN1SerializationTest.h
View
@@ -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
25 Test/Source/DTASN1SerializationTest.m
View
@@ -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
Please sign in to comment.
Something went wrong with that request. Please try again.