• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Protocol Buffers - Google's data interchange format
2// Copyright 2008 Google Inc.  All rights reserved.
3//
4// Use of this source code is governed by a BSD-style
5// license that can be found in the LICENSE file or at
6// https://developers.google.com/open-source/licenses/bsd
7
8#import "GPBCodedInputStream.h"
9#import "GPBMessage_PackagePrivate.h"
10#import "GPBTestUtilities.h"
11#import "GPBUnknownField.h"
12#import "GPBUnknownField_PackagePrivate.h"
13#import "GPBUnknownFields.h"
14#import "GPBWireFormat.h"
15#import "objectivec/Tests/Unittest.pbobjc.h"
16#import "objectivec/Tests/UnittestMset.pbobjc.h"
17
18@interface WireFormatTests : GPBTestCase
19@end
20
21@implementation WireFormatTests
22
23- (void)testSerialization {
24  TestAllTypes* message = [self allSetRepeatedCount:kGPBDefaultRepeatCount];
25
26  NSData* rawBytes = message.data;
27  [self assertFieldsInOrder:rawBytes];
28  XCTAssertEqual(message.serializedSize, (size_t)rawBytes.length);
29
30  TestAllTypes* message2 = [TestAllTypes parseFromData:rawBytes error:NULL];
31
32  [self assertAllFieldsSet:message2 repeatedCount:kGPBDefaultRepeatCount];
33}
34
35- (void)testSerializationPacked {
36  TestPackedTypes* message = [self packedSetRepeatedCount:kGPBDefaultRepeatCount];
37
38  NSData* rawBytes = message.data;
39  [self assertFieldsInOrder:rawBytes];
40  XCTAssertEqual(message.serializedSize, (size_t)rawBytes.length);
41
42  TestPackedTypes* message2 = [TestPackedTypes parseFromData:rawBytes error:NULL];
43
44  [self assertPackedFieldsSet:message2 repeatedCount:kGPBDefaultRepeatCount];
45}
46
47- (void)testSerializeExtensions {
48  // TestAllTypes and TestAllExtensions should have compatible wire formats,
49  // so if we serealize a TestAllExtensions then parse it as TestAllTypes
50  // it should work.
51
52  TestAllExtensions* message = [self allExtensionsSetRepeatedCount:kGPBDefaultRepeatCount];
53  NSData* rawBytes = message.data;
54  [self assertFieldsInOrder:rawBytes];
55  XCTAssertEqual(message.serializedSize, (size_t)rawBytes.length);
56
57  TestAllTypes* message2 = [TestAllTypes parseFromData:rawBytes error:NULL];
58
59  [self assertAllFieldsSet:message2 repeatedCount:kGPBDefaultRepeatCount];
60}
61
62- (void)testSerializePackedExtensions {
63  // TestPackedTypes and TestPackedExtensions should have compatible wire
64  // formats; check that they serialize to the same string.
65  TestPackedExtensions* message = [self packedExtensionsSetRepeatedCount:kGPBDefaultRepeatCount];
66  NSData* rawBytes = message.data;
67  [self assertFieldsInOrder:rawBytes];
68
69  TestPackedTypes* message2 = [self packedSetRepeatedCount:kGPBDefaultRepeatCount];
70  NSData* rawBytes2 = message2.data;
71
72  XCTAssertEqualObjects(rawBytes, rawBytes2);
73}
74
75- (void)testParseExtensions {
76  // TestAllTypes and TestAllExtensions should have compatible wire formats,
77  // so if we serialize a TestAllTypes then parse it as TestAllExtensions
78  // it should work.
79
80  TestAllTypes* message = [self allSetRepeatedCount:kGPBDefaultRepeatCount];
81  NSData* rawBytes = message.data;
82  [self assertFieldsInOrder:rawBytes];
83
84  GPBExtensionRegistry* registry = [self extensionRegistry];
85
86  TestAllExtensions* message2 = [TestAllExtensions parseFromData:rawBytes
87                                               extensionRegistry:registry
88                                                           error:NULL];
89
90  [self assertAllExtensionsSet:message2 repeatedCount:kGPBDefaultRepeatCount];
91}
92
93- (void)testExtensionsSerializedSize {
94  size_t allSet = [self allSetRepeatedCount:kGPBDefaultRepeatCount].serializedSize;
95  size_t extensionSet = [self allExtensionsSetRepeatedCount:kGPBDefaultRepeatCount].serializedSize;
96  XCTAssertEqual(allSet, extensionSet);
97}
98
99- (void)testParsePackedExtensions {
100  // Ensure that packed extensions can be properly parsed.
101  TestPackedExtensions* message = [self packedExtensionsSetRepeatedCount:kGPBDefaultRepeatCount];
102  NSData* rawBytes = message.data;
103  [self assertFieldsInOrder:rawBytes];
104
105  GPBExtensionRegistry* registry = [self extensionRegistry];
106
107  TestPackedExtensions* message2 = [TestPackedExtensions parseFromData:rawBytes
108                                                     extensionRegistry:registry
109                                                                 error:NULL];
110
111  [self assertPackedExtensionsSet:message2 repeatedCount:kGPBDefaultRepeatCount];
112}
113
114const int kUnknownTypeId = 1550055;
115const int kUnknownTypeId2 = 1550056;
116
117- (void)testSerializeMessageSet {
118  // Set up a MSetMessage with two known messages and an unknown one.
119  MSetMessage* message_set = [MSetMessage message];
120  [[message_set getExtension:[MSetMessageExtension1 messageSetExtension]] setI:123];
121  [[message_set getExtension:[MSetMessageExtension2 messageSetExtension]] setStr:@"foo"];
122
123#pragma clang diagnostic push
124#pragma clang diagnostic ignored "-Wdeprecated-declarations"
125  GPBUnknownField* unknownField =
126      [[[GPBUnknownField alloc] initWithNumber:kUnknownTypeId] autorelease];
127  [unknownField addLengthDelimited:DataFromCStr("bar")];
128  GPBUnknownFieldSet* unknownFieldSet = [[[GPBUnknownFieldSet alloc] init] autorelease];
129  [unknownFieldSet addField:unknownField];
130  [message_set setUnknownFields:unknownFieldSet];
131#pragma clang diagnostic pop
132
133  GPBUnknownFields* ufs = [[[GPBUnknownFields alloc] init] autorelease];
134  GPBUnknownFields* group = [ufs addGroupWithFieldNumber:GPBWireFormatMessageSetItem];
135  [group addFieldNumber:GPBWireFormatMessageSetTypeId varint:kUnknownTypeId2];
136  [group addFieldNumber:GPBWireFormatMessageSetMessage lengthDelimited:DataFromCStr("baz")];
137  XCTAssertTrue([message_set mergeUnknownFields:ufs
138                              extensionRegistry:[MSetUnittestMsetRoot extensionRegistry]
139                                          error:NULL]);
140
141  NSData* data = [message_set data];
142
143  // Parse back using MSetRawMessageSet and check the contents.
144  MSetRawMessageSet* raw = [MSetRawMessageSet parseFromData:data error:NULL];
145
146  GPBUnknownFields* ufs2 = [[[GPBUnknownFields alloc] initFromMessage:raw] autorelease];
147  XCTAssertTrue(ufs2.empty);
148#pragma clang diagnostic push
149#pragma clang diagnostic ignored "-Wdeprecated-declarations"
150  XCTAssertEqual([raw.unknownFields countOfFields], (NSUInteger)0);
151#pragma clang diagnostic pop
152
153  XCTAssertEqual(raw.itemArray.count, (NSUInteger)4);
154  XCTAssertEqual((uint32_t)[raw.itemArray[0] typeId],
155                 [MSetMessageExtension1 messageSetExtension].fieldNumber);
156  XCTAssertEqual((uint32_t)[raw.itemArray[1] typeId],
157                 [MSetMessageExtension2 messageSetExtension].fieldNumber);
158  XCTAssertEqual([raw.itemArray[2] typeId], kUnknownTypeId);
159  XCTAssertEqual([raw.itemArray[3] typeId], kUnknownTypeId2);
160
161  MSetMessageExtension1* message1 =
162      [MSetMessageExtension1 parseFromData:[((MSetRawMessageSet_Item*)raw.itemArray[0]) message]
163                                     error:NULL];
164  XCTAssertEqual(message1.i, 123);
165
166  MSetMessageExtension2* message2 =
167      [MSetMessageExtension2 parseFromData:[((MSetRawMessageSet_Item*)raw.itemArray[1]) message]
168                                     error:NULL];
169  XCTAssertEqualObjects(message2.str, @"foo");
170
171  XCTAssertEqualObjects([raw.itemArray[2] message], DataFromCStr("bar"));
172  XCTAssertEqualObjects([raw.itemArray[3] message], DataFromCStr("baz"));
173}
174
175- (void)testParseMessageSet {
176  // Set up a MSetRawMessageSet with two known messages and an unknown one.
177  MSetRawMessageSet* raw = [MSetRawMessageSet message];
178
179  {
180    MSetRawMessageSet_Item* item = [MSetRawMessageSet_Item message];
181    item.typeId = [MSetMessageExtension1 messageSetExtension].fieldNumber;
182    MSetMessageExtension1* message = [MSetMessageExtension1 message];
183    message.i = 123;
184    item.message = [message data];
185    [raw.itemArray addObject:item];
186  }
187
188  {
189    MSetRawMessageSet_Item* item = [MSetRawMessageSet_Item message];
190    item.typeId = [MSetMessageExtension2 messageSetExtension].fieldNumber;
191    MSetMessageExtension2* message = [MSetMessageExtension2 message];
192    message.str = @"foo";
193    item.message = [message data];
194    [raw.itemArray addObject:item];
195  }
196
197  {
198    MSetRawMessageSet_Item* item = [MSetRawMessageSet_Item message];
199    item.typeId = kUnknownTypeId;
200    item.message = DataFromCStr("bar");
201    [raw.itemArray addObject:item];
202  }
203
204  NSData* data = [raw data];
205
206  // Parse as a MSetMessage and check the contents.
207  MSetMessage* messageSet = [MSetMessage parseFromData:data
208                                     extensionRegistry:[MSetUnittestMsetRoot extensionRegistry]
209                                                 error:NULL];
210
211  XCTAssertEqual([[messageSet getExtension:[MSetMessageExtension1 messageSetExtension]] i], 123);
212  XCTAssertEqualObjects([[messageSet getExtension:[MSetMessageExtension2 messageSetExtension]] str],
213                        @"foo");
214
215  GPBUnknownFields* ufs = [[[GPBUnknownFields alloc] initFromMessage:messageSet] autorelease];
216  XCTAssertEqual(ufs.count, (NSUInteger)1);
217  GPBUnknownFields* group = [ufs firstGroup:GPBWireFormatMessageSetItem];
218  XCTAssertNotNil(group);
219  XCTAssertEqual(group.count, (NSUInteger)2);
220  uint64_t varint = 0;
221  XCTAssertTrue([group getFirst:GPBWireFormatMessageSetTypeId varint:&varint]);
222  XCTAssertEqual(varint, kUnknownTypeId);
223  XCTAssertEqualObjects([group firstLengthDelimited:GPBWireFormatMessageSetMessage],
224                        DataFromCStr("bar"));
225
226#pragma clang diagnostic push
227#pragma clang diagnostic ignored "-Wdeprecated-declarations"
228  XCTAssertEqual([messageSet.unknownFields countOfFields], (NSUInteger)1);
229  GPBUnknownField* unknownField = [messageSet.unknownFields getField:kUnknownTypeId];
230  XCTAssertNotNil(unknownField);
231  XCTAssertEqual(unknownField.lengthDelimitedList.count, (NSUInteger)1);
232  XCTAssertEqualObjects(unknownField.lengthDelimitedList[0], DataFromCStr("bar"));
233#pragma clang diagnostic pop
234}
235
236- (void)testParseMessageSet_FirstValueSticks {
237  MSetRawBreakableMessageSet* raw = [MSetRawBreakableMessageSet message];
238
239  {
240    MSetRawBreakableMessageSet_Item* item = [MSetRawBreakableMessageSet_Item message];
241
242    [item.typeIdArray addValue:[MSetMessageExtension1 messageSetExtension].fieldNumber];
243    MSetMessageExtension1* message1 = [MSetMessageExtension1 message];
244    message1.i = 123;
245    NSData* itemData = [message1 data];
246    [item.messageArray addObject:itemData];
247
248    [item.typeIdArray addValue:[MSetMessageExtension2 messageSetExtension].fieldNumber];
249    MSetMessageExtension2* message2 = [MSetMessageExtension2 message];
250    message2.str = @"foo";
251    itemData = [message2 data];
252    [item.messageArray addObject:itemData];
253
254    [raw.itemArray addObject:item];
255  }
256
257  NSData* data = [raw data];
258
259  // Parse as a MSetMessage and check the contents.
260  NSError* err = nil;
261  MSetMessage* messageSet = [MSetMessage parseFromData:data
262                                     extensionRegistry:[MSetUnittestMsetRoot extensionRegistry]
263                                                 error:&err];
264  XCTAssertNotNil(messageSet);
265  XCTAssertNil(err);
266  XCTAssertTrue([messageSet hasExtension:[MSetMessageExtension1 messageSetExtension]]);
267  XCTAssertEqual([[messageSet getExtension:[MSetMessageExtension1 messageSetExtension]] i], 123);
268  XCTAssertFalse([messageSet hasExtension:[MSetMessageExtension2 messageSetExtension]]);
269  GPBUnknownFields* ufs = [[[GPBUnknownFields alloc] initFromMessage:messageSet] autorelease];
270  XCTAssertTrue(ufs.empty);
271}
272
273- (void)testParseMessageSet_PartialValuesDropped {
274  MSetRawBreakableMessageSet* raw = [MSetRawBreakableMessageSet message];
275
276  {
277    MSetRawBreakableMessageSet_Item* item = [MSetRawBreakableMessageSet_Item message];
278    [item.typeIdArray addValue:[MSetMessageExtension1 messageSetExtension].fieldNumber];
279    // No payload.
280    [raw.itemArray addObject:item];
281  }
282
283  {
284    MSetRawBreakableMessageSet_Item* item = [MSetRawBreakableMessageSet_Item message];
285    // No type ID.
286    MSetMessageExtension2* message = [MSetMessageExtension2 message];
287    message.str = @"foo";
288    NSData* itemData = [message data];
289    [item.messageArray addObject:itemData];
290    [raw.itemArray addObject:item];
291  }
292
293  {
294    MSetRawBreakableMessageSet_Item* item = [MSetRawBreakableMessageSet_Item message];
295    // Neither type ID nor payload.
296    [raw.itemArray addObject:item];
297  }
298
299  NSData* data = [raw data];
300
301  // Parse as a MSetMessage and check the contents.
302  NSError* err = nil;
303  MSetMessage* messageSet = [MSetMessage parseFromData:data
304                                     extensionRegistry:[MSetUnittestMsetRoot extensionRegistry]
305                                                 error:&err];
306  XCTAssertNotNil(messageSet);
307  XCTAssertNil(err);
308  XCTAssertEqual([messageSet extensionsCurrentlySet].count,
309                 (NSUInteger)0);  // None because they were all partial and dropped.
310  GPBUnknownFields* ufs = [[[GPBUnknownFields alloc] initFromMessage:messageSet] autorelease];
311  XCTAssertTrue(ufs.empty);
312}
313
314- (void)assertFieldsInOrder:(NSData*)data {
315  GPBCodedInputStream* input = [GPBCodedInputStream streamWithData:data];
316  int32_t previousTag = 0;
317
318  while (YES) {
319    int32_t tag = [input readTag];
320    if (tag == 0) {
321      break;
322    }
323
324    XCTAssertGreaterThan(tag, previousTag);
325    [input skipField:tag];
326  }
327}
328
329@end
330