mirror of
https://github.com/MacPass/MacPass.git
synced 2025-12-14 07:02:39 +00:00
started refactoring autotype system to use tokenizer
This commit is contained in:
22
MacPass/MPToken.h
Normal file
22
MacPass/MPToken.h
Normal file
@@ -0,0 +1,22 @@
|
||||
//
|
||||
// MPToken.h
|
||||
// MacPass
|
||||
//
|
||||
// Created by Michael Starke on 07.11.17.
|
||||
// Copyright © 2017 HicknHack Software GmbH. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface MPToken : NSObject
|
||||
|
||||
@property (readonly, copy) NSString *value;
|
||||
|
||||
+ (NSArray<MPToken *> *)tokenizeString:(NSString *)string;
|
||||
- (instancetype)initWithValue:(NSString *)value NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
147
MacPass/MPToken.m
Normal file
147
MacPass/MPToken.m
Normal file
@@ -0,0 +1,147 @@
|
||||
//
|
||||
// MPToken.m
|
||||
// MacPass
|
||||
//
|
||||
// Created by Michael Starke on 07.11.17.
|
||||
// Copyright © 2017 HicknHack Software GmbH. All rights reserved.
|
||||
//
|
||||
|
||||
#import "MPToken.h"
|
||||
|
||||
#import <KeePassKit/KeePassKit.h>
|
||||
#import <Carbon/Carbon.h>
|
||||
|
||||
@interface NSString (MPTokenExtension)
|
||||
@property (nonatomic, readonly) BOOL isOpenCurlyBraket;
|
||||
@property (nonatomic, readonly) BOOL isClosingCurlyBraket;
|
||||
@end
|
||||
|
||||
@implementation NSString (MPTokenExtension)
|
||||
|
||||
- (BOOL)isOpenCurlyBraket {
|
||||
return [self isEqualToString:@"{"];
|
||||
}
|
||||
|
||||
- (BOOL)isClosingCurlyBraket {
|
||||
return [self isEqualToString:@"}"];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface MPToken ()
|
||||
|
||||
@property (copy) NSString *value;
|
||||
|
||||
@end
|
||||
|
||||
typedef NS_ENUM(NSInteger, MPTokenizeState) {
|
||||
MPTokenizeStateNormal,
|
||||
MPTokenizeStateCompoundToken,
|
||||
MPTokenizerStateError
|
||||
};
|
||||
|
||||
@implementation MPToken
|
||||
|
||||
/**
|
||||
* Mapping for modifier to CGEventFlags.
|
||||
*
|
||||
* @return dictionary with commands as keys and CGEventFlags as wrapped values
|
||||
*/
|
||||
+ (NSDictionary *)_modifierCommands {
|
||||
static NSDictionary *modifierCommands;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
modifierCommands = @{
|
||||
kKPKAutotypeAlt : @(kCGEventFlagMaskAlternate),
|
||||
kKPKAutotypeControl : @(kCGEventFlagMaskControl),
|
||||
kKPKAutotypeShift : @(kCGEventFlagMaskShift)
|
||||
};
|
||||
});
|
||||
return modifierCommands;
|
||||
}
|
||||
|
||||
+ (NSArray<MPToken *> *)tokenizeString:(NSString *)string {
|
||||
if(!string) {
|
||||
return nil;
|
||||
}
|
||||
__block NSMutableString *tokenValue = [[NSMutableString alloc] init];
|
||||
__block MPTokenizeState state = MPTokenizeStateNormal;
|
||||
__block NSMutableArray *tokens = [[NSMutableArray alloc] initWithCapacity:MAX(1,string.length)];
|
||||
[string enumerateSubstringsInRange:NSMakeRange(0, string.length)
|
||||
options:NSStringEnumerationByComposedCharacterSequences
|
||||
usingBlock:^(NSString * _Nullable substring, NSRange substringRange, NSRange enclosingRange, BOOL * _Nonnull stop) {
|
||||
switch(state) {
|
||||
case MPTokenizeStateNormal: {
|
||||
if(substring.isOpenCurlyBraket) {
|
||||
[tokenValue setString:@"{"];
|
||||
state = MPTokenizeStateCompoundToken;
|
||||
}
|
||||
else if(substring.isClosingCurlyBraket) {
|
||||
state = MPTokenizerStateError;
|
||||
}
|
||||
else {
|
||||
MPToken *token = [[MPToken alloc] initWithValue:substring];
|
||||
if(token) {
|
||||
[tokens addObject:token];
|
||||
}
|
||||
else {
|
||||
state = MPTokenizerStateError;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MPTokenizeStateCompoundToken: {
|
||||
if(substring.isOpenCurlyBraket) {
|
||||
state = MPTokenizerStateError;
|
||||
}
|
||||
else if(substring.isClosingCurlyBraket) {
|
||||
state = MPTokenizeStateNormal;
|
||||
[tokenValue appendString:@"}"];
|
||||
MPToken *token = [[MPToken alloc] initWithValue:tokenValue];
|
||||
if(token) {
|
||||
[tokens addObject:token];
|
||||
}
|
||||
else {
|
||||
state = MPTokenizerStateError;
|
||||
}
|
||||
/* clear tokenvalue */
|
||||
[tokenValue setString:@""];
|
||||
}
|
||||
else {
|
||||
[tokenValue appendString:substring];
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MPTokenizerStateError:
|
||||
default:
|
||||
state = MPTokenizerStateError;
|
||||
*stop = YES;
|
||||
break;
|
||||
}
|
||||
}];
|
||||
return [tokens copy];
|
||||
}
|
||||
|
||||
- (instancetype)init {
|
||||
self = [self initWithValue:@""];
|
||||
return self;
|
||||
}
|
||||
|
||||
- (instancetype)initWithValue:(NSString *)value {
|
||||
if(!value) {
|
||||
[[NSException exceptionWithName:NSInvalidArgumentException reason:@"Token vale cannot be nil!" userInfo:nil] raise];
|
||||
self = nil;
|
||||
return self;
|
||||
}
|
||||
self = [super init];
|
||||
if(self) {
|
||||
_value = [value copy];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSString *)description {
|
||||
return self.value.description;
|
||||
}
|
||||
|
||||
@end
|
||||
32
MacPassTests/MPTestToken.m
Normal file
32
MacPassTests/MPTestToken.m
Normal file
@@ -0,0 +1,32 @@
|
||||
//
|
||||
// MPTestToken.m
|
||||
// MacPassTests
|
||||
//
|
||||
// Created by Michael Starke on 07.11.17.
|
||||
// Copyright © 2017 HicknHack Software GmbH. All rights reserved.
|
||||
//
|
||||
|
||||
#import <XCTest/XCTest.h>
|
||||
#import "MPToken.h"
|
||||
|
||||
@interface MPTestToken : XCTestCase
|
||||
|
||||
@end
|
||||
|
||||
@implementation MPTestToken
|
||||
|
||||
- (void)setUp {
|
||||
[super setUp];
|
||||
}
|
||||
|
||||
- (void)tearDown {
|
||||
[super tearDown];
|
||||
}
|
||||
|
||||
- (void)testTokenizing {
|
||||
NSArray *tokens =[MPToken tokenizeString:@"{^}{USERNAME}^S+H{SPACE}"];
|
||||
XCTAssertEqual(7, tokens.count);
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
Reference in New Issue
Block a user