Merge branch 'charlesmchen/byteParser'

pull/1/head
Matthew Chen 7 years ago
commit c92f843530

@ -1 +1 @@
Subproject commit 5f150b04c9b18810537552c7828d8a8af93bf548
Subproject commit a2394bbafc099db434ee91e7a617c412750c44b9

@ -53,6 +53,7 @@
3421981621061A0700C57195 /* JSQMVC-README.md in Resources */ = {isa = PBXBuildFile; fileRef = 3421980C21061A0700C57195 /* JSQMVC-README.md */; };
3421981721061A0700C57195 /* JSQMVC-SIGNAL.md in Resources */ = {isa = PBXBuildFile; fileRef = 3421980D21061A0700C57195 /* JSQMVC-SIGNAL.md */; };
3421981821061A0700C57195 /* JSQMessageAvatarImageDataSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 3421980E21061A0700C57195 /* JSQMessageAvatarImageDataSource.h */; };
3421981C21061D2E00C57195 /* ByteParserTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3421981B21061D2E00C57195 /* ByteParserTest.swift */; };
34277A5E20751BDC006049F2 /* OWSQuotedMessageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 34277A5C20751BDC006049F2 /* OWSQuotedMessageView.m */; };
3427C64320F500E000EEC730 /* OWSMessageTimerView.m in Sources */ = {isa = PBXBuildFile; fileRef = 3427C64220F500DF00EEC730 /* OWSMessageTimerView.m */; };
3430FE181F7751D4000EC51B /* GiphyAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3430FE171F7751D4000EC51B /* GiphyAPI.swift */; };
@ -669,6 +670,7 @@
3421980C21061A0700C57195 /* JSQMVC-README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = "JSQMVC-README.md"; sourceTree = "<group>"; };
3421980D21061A0700C57195 /* JSQMVC-SIGNAL.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = "JSQMVC-SIGNAL.md"; sourceTree = "<group>"; };
3421980E21061A0700C57195 /* JSQMessageAvatarImageDataSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSQMessageAvatarImageDataSource.h; sourceTree = "<group>"; };
3421981B21061D2E00C57195 /* ByteParserTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ByteParserTest.swift; sourceTree = "<group>"; };
34277A5C20751BDC006049F2 /* OWSQuotedMessageView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSQuotedMessageView.m; sourceTree = "<group>"; };
34277A5D20751BDC006049F2 /* OWSQuotedMessageView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSQuotedMessageView.h; sourceTree = "<group>"; };
3427C64120F500DE00EEC730 /* OWSMessageTimerView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSMessageTimerView.h; sourceTree = "<group>"; };
@ -2334,6 +2336,7 @@
isa = PBXGroup;
children = (
3491D9A021022DB7001EF5A1 /* CDSSigningCertificateTest.m */,
3421981B21061D2E00C57195 /* ByteParserTest.swift */,
45E7A6A61E71CA7E00D44FB5 /* DisplayableTextFilterTest.swift */,
B660F6AA1C29868000687D6E /* ExceptionsTest.h */,
B660F6AB1C29868000687D6E /* ExceptionsTest.m */,
@ -3435,6 +3438,7 @@
3491D9A121022DB7001EF5A1 /* CDSSigningCertificateTest.m in Sources */,
340B02BA1FA0D6C700F9CFEC /* ConversationViewItemTest.m in Sources */,
458E383A1D6699FA0094BD24 /* OWSDeviceProvisioningURLParserTest.m in Sources */,
3421981C21061D2E00C57195 /* ByteParserTest.swift in Sources */,
45360B901F9527DA00FA666C /* SearcherTest.swift in Sources */,
B660F7561C29988E00687D6E /* PushManager.m in Sources */,
34DB0BED2011548B007B313F /* OWSDatabaseConverterTest.m in Sources */,

@ -0,0 +1,221 @@
//
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
import XCTest
@testable import Signal
class ByteParserTest: XCTestCase {
override func setUp() {
super.setUp()
}
override func tearDown() {
// Put teardown code here. This method is called after the invocation of each test method in the class.
super.tearDown()
}
func testGetShort_Empty() {
let parser = ByteParser(data: Data(), littleEndian: true)
XCTAssertNotNil(parser)
XCTAssertFalse(parser.hasError)
XCTAssertEqual(0, parser.nextShort())
XCTAssertTrue(parser.hasError)
}
func testGetShort_littleEndian() {
let data = Data(bytes: [0x01, 0x00, 0x00, 0x01, 0x01, 0x01 ])
let parser = ByteParser(data: data, littleEndian: true)
XCTAssertNotNil(parser)
XCTAssertFalse(parser.hasError)
XCTAssertEqual(1, parser.nextShort())
XCTAssertFalse(parser.hasError)
XCTAssertEqual(256, parser.nextShort())
XCTAssertFalse(parser.hasError)
XCTAssertEqual(257, parser.nextShort())
XCTAssertFalse(parser.hasError)
XCTAssertEqual(0, parser.nextShort())
XCTAssertTrue(parser.hasError)
}
func testGetShort_bigEndian() {
let data = Data(bytes: [0x01, 0x00, 0x00, 0x01, 0x01, 0x01 ])
let parser = ByteParser(data: data, littleEndian: false)
XCTAssertNotNil(parser)
XCTAssertFalse(parser.hasError)
XCTAssertEqual(256, parser.nextShort())
XCTAssertFalse(parser.hasError)
XCTAssertEqual(1, parser.nextShort())
XCTAssertFalse(parser.hasError)
XCTAssertEqual(257, parser.nextShort())
XCTAssertFalse(parser.hasError)
XCTAssertEqual(0, parser.nextShort())
XCTAssertTrue(parser.hasError)
}
func testGetInt_Empty() {
let parser = ByteParser(data: Data(), littleEndian: true)
XCTAssertNotNil(parser)
XCTAssertFalse(parser.hasError)
XCTAssertEqual(0, parser.nextInt())
XCTAssertTrue(parser.hasError)
}
func testGetInt_littleEndian() {
let data = Data(bytes: [0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00 ])
let parser = ByteParser(data: data, littleEndian: true)
XCTAssertNotNil(parser)
XCTAssertFalse(parser.hasError)
XCTAssertEqual(1, parser.nextInt())
XCTAssertFalse(parser.hasError)
XCTAssertEqual(256, parser.nextInt())
XCTAssertFalse(parser.hasError)
XCTAssertEqual(257, parser.nextInt())
XCTAssertFalse(parser.hasError)
XCTAssertEqual(0, parser.nextInt())
XCTAssertTrue(parser.hasError)
}
func testGetInt_bigEndian() {
let data = Data(bytes: [0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01 ])
let parser = ByteParser(data: data, littleEndian: false)
XCTAssertNotNil(parser)
XCTAssertFalse(parser.hasError)
XCTAssertEqual(1, parser.nextInt())
XCTAssertFalse(parser.hasError)
XCTAssertEqual(256, parser.nextInt())
XCTAssertFalse(parser.hasError)
XCTAssertEqual(257, parser.nextInt())
XCTAssertFalse(parser.hasError)
XCTAssertEqual(0, parser.nextInt())
XCTAssertTrue(parser.hasError)
}
func testGetLong_Empty() {
let parser = ByteParser(data: Data(), littleEndian: true)
XCTAssertNotNil(parser)
XCTAssertFalse(parser.hasError)
XCTAssertEqual(0, parser.nextLong())
XCTAssertTrue(parser.hasError)
}
func testGetLong_littleEndian() {
let data = Data(bytes: [0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ])
let parser = ByteParser(data: data, littleEndian: true)
XCTAssertNotNil(parser)
XCTAssertFalse(parser.hasError)
XCTAssertEqual(1, parser.nextLong())
XCTAssertFalse(parser.hasError)
XCTAssertEqual(256, parser.nextLong())
XCTAssertFalse(parser.hasError)
XCTAssertEqual(257, parser.nextLong())
XCTAssertFalse(parser.hasError)
XCTAssertEqual(0, parser.nextLong())
XCTAssertTrue(parser.hasError)
}
func testGetLong_bigEndian() {
let data = Data(bytes: [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01 ])
let parser = ByteParser(data: data, littleEndian: false)
XCTAssertNotNil(parser)
XCTAssertFalse(parser.hasError)
XCTAssertEqual(1, parser.nextLong())
XCTAssertFalse(parser.hasError)
XCTAssertEqual(256, parser.nextLong())
XCTAssertFalse(parser.hasError)
XCTAssertEqual(257, parser.nextLong())
XCTAssertFalse(parser.hasError)
XCTAssertEqual(0, parser.nextLong())
XCTAssertTrue(parser.hasError)
}
func testReadZero_Empty() {
let parser = ByteParser(data: Data(), littleEndian: true)
XCTAssertNotNil(parser)
XCTAssertFalse(parser.hasError)
XCTAssertFalse(parser.readZero(1))
XCTAssertTrue(parser.hasError)
}
func testReadZero() {
let data = Data(bytes: [0x00, 0x01, 0x00, 0x00, 0x01, 0x00])
let parser = ByteParser(data: data, littleEndian: true)
XCTAssertNotNil(parser)
XCTAssertFalse(parser.hasError)
XCTAssertTrue(parser.readZero(1))
XCTAssertFalse(parser.hasError)
XCTAssertFalse(parser.readZero(1))
XCTAssertFalse(parser.hasError)
XCTAssertTrue(parser.readZero(2))
XCTAssertFalse(parser.hasError)
XCTAssertFalse(parser.readZero(2))
XCTAssertFalse(parser.hasError)
XCTAssertFalse(parser.readZero(1))
XCTAssertTrue(parser.hasError)
}
func testReadBytes_Empty() {
let parser = ByteParser(data: Data(), littleEndian: true)
XCTAssertNotNil(parser)
XCTAssertFalse(parser.hasError)
XCTAssertNil(parser.readBytes(1))
XCTAssertTrue(parser.hasError)
}
func testReadBytes() {
let data = Data(bytes: [0x00, 0x01, 0x02, 0x03, 0x04, 0x05])
let parser = ByteParser(data: data, littleEndian: true)
XCTAssertNotNil(parser)
XCTAssertFalse(parser.hasError)
XCTAssertEqual(Data(bytes: [0x00 ]), parser.readBytes(1))
XCTAssertFalse(parser.hasError)
XCTAssertEqual(Data(bytes: [0x01 ]), parser.readBytes(1))
XCTAssertFalse(parser.hasError)
XCTAssertEqual(Data(bytes: [0x02, 0x03]), parser.readBytes(2))
XCTAssertFalse(parser.hasError)
XCTAssertEqual(Data(bytes: [0x04, 0x05]), parser.readBytes(2))
XCTAssertFalse(parser.hasError)
XCTAssertNil(parser.readBytes(1))
XCTAssertTrue(parser.hasError)
}
}

@ -3,150 +3,10 @@
//
#import "CDSQuote.h"
#import "ByteParser.h"
NS_ASSUME_NONNULL_BEGIN
@interface ByteParser : NSObject
@end
#pragma mark -
@interface ByteParser ()
@property (nonatomic, readonly) BOOL littleEndian;
@property (nonatomic, readonly) NSData *data;
@property (nonatomic) NSUInteger cursor;
@property (nonatomic) BOOL hasError;
@end
#pragma mark -
@implementation ByteParser
- (instancetype)initWithData:(NSData *)data littleEndian:(BOOL)littleEndian
{
if (self = [super init]) {
_littleEndian = littleEndian;
_data = data;
}
return self;
}
#pragma mark - Short
- (uint16_t)shortAtIndex:(NSUInteger)index
{
uint16_t value;
const size_t valueSize = sizeof(value);
OWSAssert(valueSize == 2);
if (index + valueSize > self.data.length) {
self.hasError = YES;
return 0;
}
[self.data getBytes:&value range:NSMakeRange(index, valueSize)];
if (self.littleEndian) {
return CFSwapInt16LittleToHost(value);
} else {
return CFSwapInt16BigToHost(value);
}
}
- (uint16_t)nextShort
{
uint16_t value = [self shortAtIndex:self.cursor];
self.cursor += sizeof(value);
return value;
}
#pragma mark - Int
- (uint32_t)intAtIndex:(NSUInteger)index
{
uint32_t value;
const size_t valueSize = sizeof(value);
OWSAssert(valueSize == 4);
if (index + valueSize > self.data.length) {
self.hasError = YES;
return 0;
}
[self.data getBytes:&value range:NSMakeRange(index, valueSize)];
if (self.littleEndian) {
return CFSwapInt32LittleToHost(value);
} else {
return CFSwapInt32BigToHost(value);
}
}
- (uint32_t)nextInt
{
uint32_t value = [self intAtIndex:self.cursor];
self.cursor += sizeof(value);
return value;
}
#pragma mark - Long
- (uint64_t)longAtIndex:(NSUInteger)index
{
uint64_t value;
const size_t valueSize = sizeof(value);
OWSAssert(valueSize == 8);
if (index + valueSize > self.data.length) {
self.hasError = YES;
return 0;
}
[self.data getBytes:&value range:NSMakeRange(index, valueSize)];
if (self.littleEndian) {
return CFSwapInt64LittleToHost(value);
} else {
return CFSwapInt64BigToHost(value);
}
}
- (uint64_t)nextLong
{
uint64_t value = [self longAtIndex:self.cursor];
self.cursor += sizeof(value);
return value;
}
#pragma mark -
- (BOOL)readZero:(NSUInteger)length
{
NSData *_Nullable subdata = [self readBytes:length];
if (!subdata) {
return NO;
}
uint8_t bytes[length];
[subdata getBytes:bytes range:NSMakeRange(0, length)];
for (int i = 0; i < length; i++) {
if (bytes[i] != 0) {
return NO;
}
}
return YES;
}
- (nullable NSData *)readBytes:(NSUInteger)length
{
NSUInteger index = self.cursor;
if (index + length > self.data.length) {
self.hasError = YES;
return nil;
}
NSData *_Nullable subdata = [self.data subdataWithRange:NSMakeRange(index, length)];
self.cursor += length;
return subdata;
}
@end
#pragma mark -
static const long SGX_FLAGS_INITTED = 0x0000000000000001L;
static const long SGX_FLAGS_DEBUG = 0x0000000000000002L;
static const long SGX_FLAGS_MODE64BIT = 0x0000000000000004L;

@ -0,0 +1,38 @@
//
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
NS_ASSUME_NONNULL_BEGIN
@interface ByteParser : NSObject
@property (nonatomic, readonly) BOOL hasError;
- (instancetype)init NS_UNAVAILABLE;
- (instancetype)initWithData:(NSData *)data littleEndian:(BOOL)littleEndian;
#pragma mark - Short
- (uint16_t)shortAtIndex:(NSUInteger)index;
- (uint16_t)nextShort;
#pragma mark - Int
- (uint32_t)intAtIndex:(NSUInteger)index;
- (uint32_t)nextInt;
#pragma mark - Long
- (uint64_t)longAtIndex:(NSUInteger)index;
- (uint64_t)nextLong;
#pragma mark -
- (BOOL)readZero:(NSUInteger)length;
- (nullable NSData *)readBytes:(NSUInteger)length;
@end
NS_ASSUME_NONNULL_END

@ -0,0 +1,142 @@
//
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
#import "ByteParser.h"
NS_ASSUME_NONNULL_BEGIN
@interface ByteParser ()
@property (nonatomic, readonly) BOOL littleEndian;
@property (nonatomic, readonly) NSData *data;
@property (nonatomic) NSUInteger cursor;
@property (nonatomic) BOOL hasError;
@end
#pragma mark -
@implementation ByteParser
- (instancetype)initWithData:(NSData *)data littleEndian:(BOOL)littleEndian
{
if (self = [super init]) {
_littleEndian = littleEndian;
_data = data;
}
return self;
}
#pragma mark - Short
- (uint16_t)shortAtIndex:(NSUInteger)index
{
uint16_t value;
const size_t valueSize = sizeof(value);
OWSAssert(valueSize == 2);
if (index + valueSize > self.data.length) {
self.hasError = YES;
return 0;
}
[self.data getBytes:&value range:NSMakeRange(index, valueSize)];
if (self.littleEndian) {
return CFSwapInt16LittleToHost(value);
} else {
return CFSwapInt16BigToHost(value);
}
}
- (uint16_t)nextShort
{
uint16_t value = [self shortAtIndex:self.cursor];
self.cursor += sizeof(value);
return value;
}
#pragma mark - Int
- (uint32_t)intAtIndex:(NSUInteger)index
{
uint32_t value;
const size_t valueSize = sizeof(value);
OWSAssert(valueSize == 4);
if (index + valueSize > self.data.length) {
self.hasError = YES;
return 0;
}
[self.data getBytes:&value range:NSMakeRange(index, valueSize)];
if (self.littleEndian) {
return CFSwapInt32LittleToHost(value);
} else {
return CFSwapInt32BigToHost(value);
}
}
- (uint32_t)nextInt
{
uint32_t value = [self intAtIndex:self.cursor];
self.cursor += sizeof(value);
return value;
}
#pragma mark - Long
- (uint64_t)longAtIndex:(NSUInteger)index
{
uint64_t value;
const size_t valueSize = sizeof(value);
OWSAssert(valueSize == 8);
if (index + valueSize > self.data.length) {
self.hasError = YES;
return 0;
}
[self.data getBytes:&value range:NSMakeRange(index, valueSize)];
if (self.littleEndian) {
return CFSwapInt64LittleToHost(value);
} else {
return CFSwapInt64BigToHost(value);
}
}
- (uint64_t)nextLong
{
uint64_t value = [self longAtIndex:self.cursor];
self.cursor += sizeof(value);
return value;
}
#pragma mark -
- (BOOL)readZero:(NSUInteger)length
{
NSData *_Nullable subdata = [self readBytes:length];
if (!subdata) {
return NO;
}
uint8_t bytes[length];
[subdata getBytes:bytes range:NSMakeRange(0, length)];
for (int i = 0; i < length; i++) {
if (bytes[i] != 0) {
return NO;
}
}
return YES;
}
- (nullable NSData *)readBytes:(NSUInteger)length
{
NSUInteger index = self.cursor;
if (index + length > self.data.length) {
self.hasError = YES;
return nil;
}
NSData *_Nullable subdata = [self.data subdataWithRange:NSMakeRange(index, length)];
self.cursor += length;
return subdata;
}
@end
NS_ASSUME_NONNULL_END
Loading…
Cancel
Save