1// Protocol Buffers - Google's data interchange format 2// Copyright 2008 Google Inc. All rights reserved. 3// https://developers.google.com/protocol-buffers/ 4// 5// Redistribution and use in source and binary forms, with or without 6// modification, are permitted provided that the following conditions are 7// met: 8// 9// * Redistributions of source code must retain the above copyright 10// notice, this list of conditions and the following disclaimer. 11// * Redistributions in binary form must reproduce the above 12// copyright notice, this list of conditions and the following disclaimer 13// in the documentation and/or other materials provided with the 14// distribution. 15// * Neither the name of Google Inc. nor the names of its 16// contributors may be used to endorse or promote products derived from 17// this software without specific prior written permission. 18// 19// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 31#import "GPBTestUtilities.h" 32 33#import "GPBCodedInputStream.h" 34#import "GPBMessage_PackagePrivate.h" 35#import "GPBUnknownField_PackagePrivate.h" 36#import "google/protobuf/Unittest.pbobjc.h" 37#import "google/protobuf/UnittestMset.pbobjc.h" 38#import "google/protobuf/UnittestMsetWireFormat.pbobjc.h" 39 40@interface WireFormatTests : GPBTestCase 41@end 42 43@implementation WireFormatTests 44 45- (void)testSerialization { 46 TestAllTypes* message = [self allSetRepeatedCount:kGPBDefaultRepeatCount]; 47 48 NSData* rawBytes = message.data; 49 [self assertFieldsInOrder:rawBytes]; 50 XCTAssertEqual(message.serializedSize, (size_t)rawBytes.length); 51 52 TestAllTypes* message2 = [TestAllTypes parseFromData:rawBytes error:NULL]; 53 54 [self assertAllFieldsSet:message2 repeatedCount:kGPBDefaultRepeatCount]; 55} 56 57- (void)testSerializationPacked { 58 TestPackedTypes* message = 59 [self packedSetRepeatedCount:kGPBDefaultRepeatCount]; 60 61 NSData* rawBytes = message.data; 62 [self assertFieldsInOrder:rawBytes]; 63 XCTAssertEqual(message.serializedSize, (size_t)rawBytes.length); 64 65 TestPackedTypes* message2 = 66 [TestPackedTypes parseFromData:rawBytes error:NULL]; 67 68 [self assertPackedFieldsSet:message2 repeatedCount:kGPBDefaultRepeatCount]; 69} 70 71- (void)testSerializeExtensions { 72 // TestAllTypes and TestAllExtensions should have compatible wire formats, 73 // so if we serealize a TestAllExtensions then parse it as TestAllTypes 74 // it should work. 75 76 TestAllExtensions* message = 77 [self allExtensionsSetRepeatedCount:kGPBDefaultRepeatCount]; 78 NSData* rawBytes = message.data; 79 [self assertFieldsInOrder:rawBytes]; 80 XCTAssertEqual(message.serializedSize, (size_t)rawBytes.length); 81 82 TestAllTypes* message2 = [TestAllTypes parseFromData:rawBytes error:NULL]; 83 84 [self assertAllFieldsSet:message2 repeatedCount:kGPBDefaultRepeatCount]; 85} 86 87- (void)testSerializePackedExtensions { 88 // TestPackedTypes and TestPackedExtensions should have compatible wire 89 // formats; check that they serialize to the same string. 90 TestPackedExtensions* message = 91 [self packedExtensionsSetRepeatedCount:kGPBDefaultRepeatCount]; 92 NSData* rawBytes = message.data; 93 [self assertFieldsInOrder:rawBytes]; 94 95 TestPackedTypes* message2 = 96 [self packedSetRepeatedCount:kGPBDefaultRepeatCount]; 97 NSData* rawBytes2 = message2.data; 98 99 XCTAssertEqualObjects(rawBytes, rawBytes2); 100} 101 102- (void)testParseExtensions { 103 // TestAllTypes and TestAllExtensions should have compatible wire formats, 104 // so if we serialize a TestAllTypes then parse it as TestAllExtensions 105 // it should work. 106 107 TestAllTypes* message = [self allSetRepeatedCount:kGPBDefaultRepeatCount]; 108 NSData* rawBytes = message.data; 109 [self assertFieldsInOrder:rawBytes]; 110 111 GPBExtensionRegistry* registry = [self extensionRegistry]; 112 113 TestAllExtensions* message2 = [TestAllExtensions parseFromData:rawBytes 114 extensionRegistry:registry 115 error:NULL]; 116 117 [self assertAllExtensionsSet:message2 repeatedCount:kGPBDefaultRepeatCount]; 118} 119 120 121- (void)testExtensionsSerializedSize { 122 size_t allSet = [self allSetRepeatedCount:kGPBDefaultRepeatCount].serializedSize; 123 size_t extensionSet = [self allExtensionsSetRepeatedCount:kGPBDefaultRepeatCount].serializedSize; 124 XCTAssertEqual(allSet, extensionSet); 125} 126 127- (void)testParsePackedExtensions { 128 // Ensure that packed extensions can be properly parsed. 129 TestPackedExtensions* message = 130 [self packedExtensionsSetRepeatedCount:kGPBDefaultRepeatCount]; 131 NSData* rawBytes = message.data; 132 [self assertFieldsInOrder:rawBytes]; 133 134 GPBExtensionRegistry* registry = [self extensionRegistry]; 135 136 TestPackedExtensions* message2 = [TestPackedExtensions parseFromData:rawBytes 137 extensionRegistry:registry 138 error:NULL]; 139 140 [self assertPackedExtensionsSet:message2 141 repeatedCount:kGPBDefaultRepeatCount]; 142} 143 144const int kUnknownTypeId = 1550055; 145 146- (void)testSerializeMessageSet { 147 // Set up a TestMessageSet with two known messages and an unknown one. 148 TestMessageSet* message_set = [TestMessageSet message]; 149 [[message_set getExtension:[TestMessageSetExtension1 messageSetExtension]] 150 setI:123]; 151 [[message_set getExtension:[TestMessageSetExtension2 messageSetExtension]] 152 setStr:@"foo"]; 153 GPBUnknownField* unknownField = 154 [[[GPBUnknownField alloc] initWithNumber:kUnknownTypeId] autorelease]; 155 [unknownField addLengthDelimited:[NSData dataWithBytes:"bar" length:3]]; 156 GPBUnknownFieldSet* unknownFieldSet = 157 [[[GPBUnknownFieldSet alloc] init] autorelease]; 158 [unknownFieldSet addField:unknownField]; 159 [message_set setUnknownFields:unknownFieldSet]; 160 161 NSData* data = [message_set data]; 162 163 // Parse back using RawMessageSet and check the contents. 164 RawMessageSet* raw = [RawMessageSet parseFromData:data error:NULL]; 165 166 XCTAssertEqual([raw.unknownFields countOfFields], (NSUInteger)0); 167 168 XCTAssertEqual(raw.itemArray.count, (NSUInteger)3); 169 XCTAssertEqual((uint32_t)[raw.itemArray[0] typeId], 170 [TestMessageSetExtension1 messageSetExtension].fieldNumber); 171 XCTAssertEqual((uint32_t)[raw.itemArray[1] typeId], 172 [TestMessageSetExtension2 messageSetExtension].fieldNumber); 173 XCTAssertEqual([raw.itemArray[2] typeId], kUnknownTypeId); 174 175 TestMessageSetExtension1* message1 = 176 [TestMessageSetExtension1 parseFromData:[((RawMessageSet_Item*)raw.itemArray[0]) message] 177 error:NULL]; 178 XCTAssertEqual(message1.i, 123); 179 180 TestMessageSetExtension2* message2 = 181 [TestMessageSetExtension2 parseFromData:[((RawMessageSet_Item*)raw.itemArray[1]) message] 182 error:NULL]; 183 XCTAssertEqualObjects(message2.str, @"foo"); 184 185 XCTAssertEqualObjects([raw.itemArray[2] message], 186 [NSData dataWithBytes:"bar" length:3]); 187} 188 189- (void)testParseMessageSet { 190 // Set up a RawMessageSet with two known messages and an unknown one. 191 RawMessageSet* raw = [RawMessageSet message]; 192 193 { 194 RawMessageSet_Item* item = [RawMessageSet_Item message]; 195 item.typeId = [TestMessageSetExtension1 messageSetExtension].fieldNumber; 196 TestMessageSetExtension1* message = [TestMessageSetExtension1 message]; 197 message.i = 123; 198 item.message = [message data]; 199 [raw.itemArray addObject:item]; 200 } 201 202 { 203 RawMessageSet_Item* item = [RawMessageSet_Item message]; 204 item.typeId = [TestMessageSetExtension2 messageSetExtension].fieldNumber; 205 TestMessageSetExtension2* message = [TestMessageSetExtension2 message]; 206 message.str = @"foo"; 207 item.message = [message data]; 208 [raw.itemArray addObject:item]; 209 } 210 211 { 212 RawMessageSet_Item* item = [RawMessageSet_Item message]; 213 item.typeId = kUnknownTypeId; 214 item.message = [NSData dataWithBytes:"bar" length:3]; 215 [raw.itemArray addObject:item]; 216 } 217 218 NSData* data = [raw data]; 219 220 // Parse as a TestMessageSet and check the contents. 221 TestMessageSet* messageSet = 222 [TestMessageSet parseFromData:data 223 extensionRegistry:[UnittestMsetRoot extensionRegistry] 224 error:NULL]; 225 226 XCTAssertEqual( 227 [[messageSet 228 getExtension:[TestMessageSetExtension1 messageSetExtension]] i], 229 123); 230 XCTAssertEqualObjects( 231 [[messageSet 232 getExtension:[TestMessageSetExtension2 messageSetExtension]] str], 233 @"foo"); 234 235 XCTAssertEqual([messageSet.unknownFields countOfFields], (NSUInteger)1); 236 GPBUnknownField* unknownField = [messageSet.unknownFields getField:kUnknownTypeId]; 237 XCTAssertNotNil(unknownField); 238 XCTAssertEqual(unknownField.lengthDelimitedList.count, (NSUInteger)1); 239 XCTAssertEqualObjects(unknownField.lengthDelimitedList[0], 240 [NSData dataWithBytes:"bar" length:3]); 241} 242 243- (void)assertFieldsInOrder:(NSData*)data { 244 GPBCodedInputStream* input = [GPBCodedInputStream streamWithData:data]; 245 int32_t previousTag = 0; 246 247 while (YES) { 248 int32_t tag = [input readTag]; 249 if (tag == 0) { 250 break; 251 } 252 253 XCTAssertGreaterThan(tag, previousTag); 254 [input skipField:tag]; 255 } 256} 257 258@end 259