mirror of
https://github.com/oxen-io/session-ios.git
synced 2023-12-13 21:30:14 +01:00
0b49037179
// FREEBIE
103 lines
4.2 KiB
Objective-C
103 lines
4.2 KiB
Objective-C
//
|
|
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
|
//
|
|
|
|
#import "NumberUtil.h"
|
|
#import "StringUtil.h"
|
|
|
|
@implementation NSString (Util)
|
|
- (NSData *)decodedAsHexString {
|
|
ows_require(self.length % 2 == 0);
|
|
|
|
NSUInteger n = self.length / 2;
|
|
uint8_t result[n];
|
|
for (NSUInteger i = 0; i < n; i++) {
|
|
unsigned int r;
|
|
NSScanner *scanner = [NSScanner scannerWithString:[self substringWithRange:NSMakeRange(i * 2, 2)]];
|
|
checkOperation([scanner scanHexInt:&r]);
|
|
checkOperation(r < 256);
|
|
result[i] = (uint8_t)r;
|
|
}
|
|
return [NSData dataWithBytes:result length:sizeof(result)];
|
|
}
|
|
- (NSData *)encodedAsUtf8 {
|
|
NSData *result = [self dataUsingEncoding:NSUTF8StringEncoding];
|
|
checkOperationDescribe(result != nil, @"Not a UTF8 string.");
|
|
return result;
|
|
}
|
|
- (NSData *)encodedAsAscii {
|
|
NSData *result = [self dataUsingEncoding:NSASCIIStringEncoding];
|
|
checkOperationDescribe(result != nil, @"Not an ascii string.");
|
|
return result;
|
|
}
|
|
- (NSRegularExpression *)toRegularExpression {
|
|
NSError *regexInitError = NULL;
|
|
NSRegularExpression *regex =
|
|
[NSRegularExpression regularExpressionWithPattern:self options:0 error:®exInitError];
|
|
checkOperation(regex != nil && regexInitError == NULL);
|
|
return regex;
|
|
}
|
|
- (NSString *)withMatchesAgainst:(NSRegularExpression *)regex replacedBy:(NSString *)replacement {
|
|
ows_require(regex != nil);
|
|
ows_require(replacement != nil);
|
|
NSMutableString *m = self.mutableCopy;
|
|
[regex replaceMatchesInString:m options:0 range:NSMakeRange(0, m.length) withTemplate:replacement];
|
|
return m;
|
|
}
|
|
- (bool)containsAnyMatches:(NSRegularExpression *)regex {
|
|
ows_require(regex != nil);
|
|
return [regex numberOfMatchesInString:self options:0 range:NSMakeRange(0, self.length)] > 0;
|
|
}
|
|
- (NSString *)withPrefixRemovedElseNull:(NSString *)prefix {
|
|
ows_require(prefix != nil);
|
|
if (prefix.length > 0 && ![self hasPrefix:prefix])
|
|
return nil;
|
|
return [self substringFromIndex:prefix.length];
|
|
}
|
|
- (NSData *)decodedAsJsonIntoData {
|
|
NSError *jsonParseError = nil;
|
|
id parsedJson = [NSJSONSerialization dataWithJSONObject:self.encodedAsUtf8 options:0 error:&jsonParseError];
|
|
checkOperationDescribe(jsonParseError == nil, ([NSString stringWithFormat:@"Invalid json: %@", self]));
|
|
checkOperationDescribe([parsedJson isKindOfClass:NSData.class], @"Unexpected json data");
|
|
return parsedJson;
|
|
}
|
|
- (NSDictionary *)decodedAsJsonIntoDictionary {
|
|
NSError *jsonParseError = nil;
|
|
id parsedJson = [NSJSONSerialization JSONObjectWithData:self.encodedAsUtf8 options:0 error:&jsonParseError];
|
|
checkOperationDescribe(jsonParseError == nil,
|
|
([NSString stringWithFormat:@"Json parse error: %@, on json: %@", jsonParseError, self]));
|
|
checkOperationDescribe([parsedJson isKindOfClass:NSDictionary.class], @"Unexpected json data");
|
|
return parsedJson;
|
|
}
|
|
- (NSNumber *)tryParseAsDecimalNumber {
|
|
NSNumberFormatter *formatter = [NSNumberFormatter new];
|
|
[formatter setNumberStyle:NSNumberFormatterDecimalStyle];
|
|
|
|
// NSNumberFormatter.numberFromString is good at noticing bad inputs, but loses precision for large values
|
|
// NSDecimalNumber.decimalNumberWithString has perfect precision, but lets bad inputs through sometimes (e.g.
|
|
// "88ffhih" -> 88)
|
|
// We use both to get both accuracy and detection of bad inputs
|
|
if ([formatter numberFromString:self] == nil) {
|
|
return nil;
|
|
}
|
|
return [NSDecimalNumber decimalNumberWithString:self];
|
|
}
|
|
- (NSNumber *)tryParseAsUnsignedInteger {
|
|
NSNumber *value = [self tryParseAsDecimalNumber];
|
|
return value.hasUnsignedIntegerValue ? value : nil;
|
|
}
|
|
- (NSString *)removeAllCharactersIn:(NSCharacterSet *)characterSet {
|
|
ows_require(characterSet != nil);
|
|
return [[self componentsSeparatedByCharactersInSet:characterSet] componentsJoinedByString:@""];
|
|
}
|
|
- (NSString *)digitsOnly {
|
|
return [self removeAllCharactersIn:[NSCharacterSet.decimalDigitCharacterSet invertedSet]];
|
|
}
|
|
- (NSString *)withCharactersInRange:(NSRange)range replacedBy:(NSString *)substring {
|
|
NSMutableString *result = self.mutableCopy;
|
|
[result replaceCharactersInRange:range withString:substring];
|
|
return result;
|
|
}
|
|
|
|
@end
|