|
|
|
@ -62,52 +62,101 @@ |
|
|
|
|
#define bytes(...) [self bytes_with_sentinel:0, __VA_ARGS__, 256] |
|
|
|
|
|
|
|
|
|
- (void)testDecodeZigZag { |
|
|
|
|
XCTAssertEqual(0, GPBDecodeZigZag32(0)); |
|
|
|
|
XCTAssertEqual(-1, GPBDecodeZigZag32(1)); |
|
|
|
|
XCTAssertEqual(1, GPBDecodeZigZag32(2)); |
|
|
|
|
XCTAssertEqual(-2, GPBDecodeZigZag32(3)); |
|
|
|
|
XCTAssertEqual((int32_t)0x3FFFFFFF, GPBDecodeZigZag32(0x7FFFFFFE)); |
|
|
|
|
XCTAssertEqual((int32_t)0xC0000000, GPBDecodeZigZag32(0x7FFFFFFF)); |
|
|
|
|
XCTAssertEqual((int32_t)0x7FFFFFFF, GPBDecodeZigZag32(0xFFFFFFFE)); |
|
|
|
|
XCTAssertEqual((int32_t)0x80000000, GPBDecodeZigZag32(0xFFFFFFFF)); |
|
|
|
|
|
|
|
|
|
XCTAssertEqual((int64_t)0, GPBDecodeZigZag64(0)); |
|
|
|
|
XCTAssertEqual((int64_t)-1, GPBDecodeZigZag64(1)); |
|
|
|
|
XCTAssertEqual((int64_t)1, GPBDecodeZigZag64(2)); |
|
|
|
|
XCTAssertEqual((int64_t)-2, GPBDecodeZigZag64(3)); |
|
|
|
|
XCTAssertEqual((int64_t)0x000000003FFFFFFFL, |
|
|
|
|
GPBDecodeZigZag64(0x000000007FFFFFFEL)); |
|
|
|
|
XCTAssertEqual((int64_t)0xFFFFFFFFC0000000L, |
|
|
|
|
GPBDecodeZigZag64(0x000000007FFFFFFFL)); |
|
|
|
|
XCTAssertEqual((int64_t)0x000000007FFFFFFFL, |
|
|
|
|
GPBDecodeZigZag64(0x00000000FFFFFFFEL)); |
|
|
|
|
XCTAssertEqual((int64_t)0xFFFFFFFF80000000L, |
|
|
|
|
GPBDecodeZigZag64(0x00000000FFFFFFFFL)); |
|
|
|
|
XCTAssertEqual((int64_t)0x7FFFFFFFFFFFFFFFL, |
|
|
|
|
GPBDecodeZigZag64(0xFFFFFFFFFFFFFFFEL)); |
|
|
|
|
XCTAssertEqual((int64_t)0x8000000000000000L, |
|
|
|
|
GPBDecodeZigZag64(0xFFFFFFFFFFFFFFFFL)); |
|
|
|
|
[self assertReadZigZag32:bytes(0x0) value:0]; |
|
|
|
|
[self assertReadZigZag32:bytes(0x1) value:-1]; |
|
|
|
|
[self assertReadZigZag32:bytes(0x2) value:1]; |
|
|
|
|
[self assertReadZigZag32:bytes(0x3) value:-2]; |
|
|
|
|
|
|
|
|
|
[self assertReadZigZag32:bytes(0xFE, 0xFF, 0xFF, 0xFF, 0x07) value:(int32_t)0x3FFFFFFF]; |
|
|
|
|
[self assertReadZigZag32:bytes(0xFF, 0xFF, 0xFF, 0xFF, 0x07) value:(int32_t)0xC0000000]; |
|
|
|
|
[self assertReadZigZag32:bytes(0xFE, 0xFF, 0xFF, 0xFF, 0x0F) value:(int32_t)0x7FFFFFFF]; |
|
|
|
|
[self assertReadZigZag32:bytes(0xFF, 0xFF, 0xFF, 0xFF, 0x0F) value:(int32_t)0x80000000]; |
|
|
|
|
|
|
|
|
|
[self assertReadZigZag64:bytes(0x0) value:0]; |
|
|
|
|
[self assertReadZigZag64:bytes(0x1) value:-1]; |
|
|
|
|
[self assertReadZigZag64:bytes(0x2) value:1]; |
|
|
|
|
[self assertReadZigZag64:bytes(0x3) value:-2]; |
|
|
|
|
|
|
|
|
|
[self assertReadZigZag64:bytes(0xFE, 0xFF, 0xFF, 0xFF, 0x07) value:(int32_t)0x3FFFFFFF]; |
|
|
|
|
[self assertReadZigZag64:bytes(0xFF, 0xFF, 0xFF, 0xFF, 0x07) value:(int32_t)0xC0000000]; |
|
|
|
|
[self assertReadZigZag64:bytes(0xFE, 0xFF, 0xFF, 0xFF, 0x0F) value:(int32_t)0x7FFFFFFF]; |
|
|
|
|
[self assertReadZigZag64:bytes(0xFF, 0xFF, 0xFF, 0xFF, 0x0F) value:(int32_t)0x80000000]; |
|
|
|
|
|
|
|
|
|
[self assertReadZigZag64:bytes(0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01) value:0x7FFFFFFFFFFFFFFFL]; |
|
|
|
|
[self assertReadZigZag64:bytes(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01) value:0x8000000000000000L]; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
- (void)assertReadVarint:(NSData*)data value:(int64_t)value { |
|
|
|
|
{ |
|
|
|
|
if (value <= INT32_MAX && value >= INT32_MIN) { |
|
|
|
|
{ |
|
|
|
|
GPBCodedInputStream* input = [GPBCodedInputStream streamWithData:data]; |
|
|
|
|
XCTAssertEqual((int32_t)value, [input readInt32]); |
|
|
|
|
} |
|
|
|
|
{ |
|
|
|
|
GPBCodedInputStream* input = [GPBCodedInputStream streamWithData:data]; |
|
|
|
|
XCTAssertEqual((int32_t)value, [input readEnum]); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if (value <= UINT32_MAX && value >= 0) { |
|
|
|
|
GPBCodedInputStream* input = [GPBCodedInputStream streamWithData:data]; |
|
|
|
|
XCTAssertEqual((int32_t)value, [input readInt32]); |
|
|
|
|
XCTAssertEqual((uint32_t)value, [input readUInt32]); |
|
|
|
|
} |
|
|
|
|
{ |
|
|
|
|
GPBCodedInputStream* input = [GPBCodedInputStream streamWithData:data]; |
|
|
|
|
XCTAssertEqual(value, [input readInt64]); |
|
|
|
|
} |
|
|
|
|
if (value >= 0) { |
|
|
|
|
GPBCodedInputStream* input = [GPBCodedInputStream streamWithData:data]; |
|
|
|
|
XCTAssertEqual((uint64_t)value, [input readUInt64]); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
- (void)assertReadLittleEndian32:(NSData*)data value:(int32_t)value { |
|
|
|
|
GPBCodedInputStream* input = [GPBCodedInputStream streamWithData:data]; |
|
|
|
|
XCTAssertEqual(value, [input readSFixed32]); |
|
|
|
|
{ |
|
|
|
|
GPBCodedInputStream* input = [GPBCodedInputStream streamWithData:data]; |
|
|
|
|
XCTAssertEqual(value, [input readSFixed32]); |
|
|
|
|
} |
|
|
|
|
{ |
|
|
|
|
GPBCodedInputStream* input = [GPBCodedInputStream streamWithData:data]; |
|
|
|
|
XCTAssertEqual(GPBConvertInt32ToFloat(value), [input readFloat]); |
|
|
|
|
} |
|
|
|
|
{ |
|
|
|
|
GPBCodedInputStream* input = [GPBCodedInputStream streamWithData:data]; |
|
|
|
|
XCTAssertEqual((uint32_t)value, [input readFixed32]); |
|
|
|
|
} |
|
|
|
|
{ |
|
|
|
|
GPBCodedInputStream* input = [GPBCodedInputStream streamWithData:data]; |
|
|
|
|
XCTAssertEqual(value, [input readSFixed32]); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
- (void)assertReadLittleEndian64:(NSData*)data value:(int64_t)value { |
|
|
|
|
{ |
|
|
|
|
GPBCodedInputStream* input = [GPBCodedInputStream streamWithData:data]; |
|
|
|
|
XCTAssertEqual(value, [input readSFixed64]); |
|
|
|
|
} |
|
|
|
|
{ |
|
|
|
|
GPBCodedInputStream* input = [GPBCodedInputStream streamWithData:data]; |
|
|
|
|
XCTAssertEqual(GPBConvertInt64ToDouble(value), [input readDouble]); |
|
|
|
|
} |
|
|
|
|
{ |
|
|
|
|
GPBCodedInputStream* input = [GPBCodedInputStream streamWithData:data]; |
|
|
|
|
XCTAssertEqual((uint64_t)value, [input readFixed64]); |
|
|
|
|
} |
|
|
|
|
{ |
|
|
|
|
GPBCodedInputStream* input = [GPBCodedInputStream streamWithData:data]; |
|
|
|
|
XCTAssertEqual(value, [input readSFixed64]); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
- (void)assertReadZigZag32:(NSData*)data value:(int64_t)value { |
|
|
|
|
GPBCodedInputStream* input = [GPBCodedInputStream streamWithData:data]; |
|
|
|
|
XCTAssertEqual((int32_t)value, [input readSInt32]); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
- (void)assertReadZigZag64:(NSData*)data value:(int64_t)value { |
|
|
|
|
GPBCodedInputStream* input = [GPBCodedInputStream streamWithData:data]; |
|
|
|
|
XCTAssertEqual(value, [input readSFixed64]); |
|
|
|
|
XCTAssertEqual(value, [input readSInt64]); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
- (void)assertReadVarintFailure:(NSData*)data { |
|
|
|
@ -128,12 +177,28 @@ |
|
|
|
|
XCTAssertEqual(((uint8_t*)data.bytes)[1], (uint8_t)0x74); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
- (void)testReadBool { |
|
|
|
|
{ |
|
|
|
|
GPBCodedInputStream* input = [GPBCodedInputStream streamWithData:bytes(0x00)]; |
|
|
|
|
XCTAssertEqual(NO, [input readBool]); |
|
|
|
|
} |
|
|
|
|
{ |
|
|
|
|
GPBCodedInputStream* input = [GPBCodedInputStream streamWithData:bytes(0x01)]; |
|
|
|
|
XCTAssertEqual(YES, [input readBool]); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
- (void)testReadVarint { |
|
|
|
|
[self assertReadVarint:bytes(0x00) value:0]; |
|
|
|
|
[self assertReadVarint:bytes(0x01) value:1]; |
|
|
|
|
[self assertReadVarint:bytes(0x7f) value:127]; |
|
|
|
|
// 14882 |
|
|
|
|
[self assertReadVarint:bytes(0xa2, 0x74) value:(0x22 << 0) | (0x74 << 7)]; |
|
|
|
|
// 1904930 |
|
|
|
|
[self assertReadVarint:bytes(0xa2, 0xa2, 0x74) value:(0x22 << 0) | (0x22 << 7) | (0x74 << 14)]; |
|
|
|
|
// 243831074 |
|
|
|
|
[self assertReadVarint:bytes(0xa2, 0xa2, 0xa2, 0x74) |
|
|
|
|
value:(0x22 << 0) | (0x22 << 7) | (0x22 << 14) | (0x74 << 21)]; |
|
|
|
|
// 2961488830 |
|
|
|
|
[self assertReadVarint:bytes(0xbe, 0xf7, 0x92, 0x84, 0x0b) |
|
|
|
|
value:(0x3e << 0) | (0x77 << 7) | (0x12 << 14) | |
|
|
|
@ -163,6 +228,45 @@ |
|
|
|
|
[self assertReadVarintFailure:bytes(0x80)]; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
- (void)testReadVarint32FromVarint64 { |
|
|
|
|
{ |
|
|
|
|
// Turn on lower 31 bits of the upper half on a 64 bit varint. |
|
|
|
|
NSData* data = bytes(0x80, 0x80, 0x80, 0x80, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E); |
|
|
|
|
|
|
|
|
|
int32_t value32 = 0x0; |
|
|
|
|
GPBCodedInputStream* input32 = [GPBCodedInputStream streamWithData:data]; |
|
|
|
|
XCTAssertEqual(value32, [input32 readInt32]); |
|
|
|
|
|
|
|
|
|
int64_t value64 = INT64_MAX & 0xFFFFFFFF00000000; |
|
|
|
|
GPBCodedInputStream* input64 = [GPBCodedInputStream streamWithData:data]; |
|
|
|
|
XCTAssertEqual(value64, [input64 readInt64]); |
|
|
|
|
} |
|
|
|
|
{ |
|
|
|
|
// Turn on lower 31 bits and lower 31 bits on upper half on a 64 bit varint. |
|
|
|
|
NSData* data = bytes(0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E); |
|
|
|
|
|
|
|
|
|
int32_t value32 = INT32_MAX; |
|
|
|
|
GPBCodedInputStream* input32 = [GPBCodedInputStream streamWithData:data]; |
|
|
|
|
XCTAssertEqual(value32, [input32 readInt32]); |
|
|
|
|
|
|
|
|
|
int64_t value64 = INT64_MAX & 0xFFFFFFFF7FFFFFFF; |
|
|
|
|
GPBCodedInputStream* input64 = [GPBCodedInputStream streamWithData:data]; |
|
|
|
|
XCTAssertEqual(value64, [input64 readInt64]); |
|
|
|
|
} |
|
|
|
|
{ |
|
|
|
|
// Turn on bits 32 and 64 bit on a 64 bit varint. |
|
|
|
|
NSData* data = bytes(0x80, 0x80, 0x80, 0x80, 0x88, 0x80, 0x80, 0x80, 0x80, 0x01); |
|
|
|
|
|
|
|
|
|
int32_t value32 = INT32_MIN; |
|
|
|
|
GPBCodedInputStream* input32 = [GPBCodedInputStream streamWithData:data]; |
|
|
|
|
XCTAssertEqual(value32, [input32 readInt32]); |
|
|
|
|
|
|
|
|
|
int64_t value64 = INT64_MIN | (0x01L << 31); |
|
|
|
|
GPBCodedInputStream* input64 = [GPBCodedInputStream streamWithData:data]; |
|
|
|
|
XCTAssertEqual(value64, [input64 readInt64]); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
- (void)testReadLittleEndian { |
|
|
|
|
[self assertReadLittleEndian32:bytes(0x78, 0x56, 0x34, 0x12) |
|
|
|
|
value:0x12345678]; |
|
|
|
@ -265,6 +369,27 @@ |
|
|
|
|
XCTAssertThrows([input readBytes]); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
- (void)testReadEmptyString { |
|
|
|
|
NSData *data = bytes(0x00); |
|
|
|
|
GPBCodedInputStream* input = [GPBCodedInputStream streamWithData:data]; |
|
|
|
|
XCTAssertEqualObjects(@"", [input readString]); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
- (void)testInvalidGroupEndTagThrows { |
|
|
|
|
NSData *data = bytes(0x0B, 0x1A, 0x02, 0x4B, 0x50, 0x14); |
|
|
|
|
GPBCodedInputStream* input = [GPBCodedInputStream streamWithData:data]; |
|
|
|
|
XCTAssertThrowsSpecificNamed([input skipMessage], |
|
|
|
|
NSException, |
|
|
|
|
GPBCodedInputStreamException, |
|
|
|
|
@"should throw a GPBCodedInputStreamException exception "); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
- (void)testBytesWithNegativeSize { |
|
|
|
|
NSData *data = bytes(0xFF, 0xFF, 0xFF, 0xFF, 0x0F); |
|
|
|
|
GPBCodedInputStream *input = [GPBCodedInputStream streamWithData:data]; |
|
|
|
|
XCTAssertNil([input readBytes]); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Verifies fix for b/10315336. |
|
|
|
|
// Note: Now that there isn't a custom string class under the hood, this test |
|
|
|
|
// isn't as critical, but it does cover bad input and if a custom class is added |
|
|
|
|