[ObjC] Start of the internal api for `GPBUnknownFields`

Add in the support for pushing the data back onto a `GPBMessage`.

PiperOrigin-RevId: 649125923
pull/17324/head
Thomas Van Lenten 9 months ago committed by Copybara-Service
parent 096b139192
commit 6e5a867f3d
  1. 4
      objectivec/BUILD.bazel
  2. 13
      objectivec/GPBMessage.h
  3. 11
      objectivec/GPBMessage.m
  4. 123
      objectivec/GPBUnknownField.m
  5. 40
      objectivec/GPBUnknownFields.m
  6. 20
      objectivec/GPBUnknownFields_PackagePrivate.h
  7. 4
      objectivec/ProtocolBuffers_OSX.xcodeproj/project.pbxproj
  8. 4
      objectivec/ProtocolBuffers_iOS.xcodeproj/project.pbxproj
  9. 4
      objectivec/ProtocolBuffers_tvOS.xcodeproj/project.pbxproj
  10. 16
      objectivec/Tests/GPBTestUtilities.h
  11. 65
      objectivec/Tests/GPBUnknownFieldsTest.m

@ -59,6 +59,10 @@ staleness_test(
objc_library(
name = "objectivec",
srcs = [
# Private headers that aren't used from the generated sources.
"GPBUnknownFields_PackagePrivate.h",
],
hdrs = [
"GPBAny.pbobjc.h",
"GPBApi.pbobjc.h",

@ -16,6 +16,7 @@
@class GPBExtensionDescriptor;
@class GPBFieldDescriptor;
@class GPBUnknownFieldSet;
@class GPBUnknownFields;
NS_ASSUME_NONNULL_BEGIN
@ -502,6 +503,18 @@ CF_EXTERN_C_END
**/
- (void)clearUnknownFields;
/**
* Merges in the data from an `GPBUnknownFields`, meaning the data from the unknown fields gets
* re-parsed so any known fields will be propertly set.
*
* If the intent is to replace the message's unknown fields, call `-clearUnknownFields` first.
*
* @param unknownFields The unknown fields to merge the data from.
* @param extensionRegistry The extension registry to use to look up extensions, can be `nil`.
**/
- (void)mergeUnknownFields:(GPBUnknownFields *)unknownFields
extensionRegistry:(nullable id<GPBExtensionRegistry>)extensionRegistry;
@end
NS_ASSUME_NONNULL_END

@ -22,6 +22,7 @@
#import "GPBExtensionRegistry.h"
#import "GPBRootObject_PackagePrivate.h"
#import "GPBUnknownFieldSet_PackagePrivate.h"
#import "GPBUnknownFields_PackagePrivate.h"
#import "GPBUtilities_PackagePrivate.h"
// Returns a new instance that was automatically created by |autocreator| for
@ -1255,6 +1256,16 @@ static GPBUnknownFieldSet *GetOrMakeUnknownFields(GPBMessage *self) {
self.unknownFields = nil;
}
- (void)mergeUnknownFields:(GPBUnknownFields *)unknownFields
extensionRegistry:(nullable id<GPBExtensionRegistry>)extensionRegistry {
NSData *data = [unknownFields serializeAsData];
if (![self mergeFromData:data extensionRegistry:extensionRegistry error:NULL]) {
#if defined(DEBUG) && DEBUG
NSAssert(0, @"Internal error within the library, failed to parse data from unknown fields.");
#endif
};
}
- (BOOL)isInitialized {
GPBDescriptor *descriptor = [self descriptor];
for (GPBFieldDescriptor *field in descriptor->fields_) {

@ -7,10 +7,12 @@
#import "GPBUnknownField.h"
#import "GPBUnknownField_PackagePrivate.h"
#import "GPBWireFormat.h"
#import "GPBArray.h"
#import "GPBCodedOutputStream_PackagePrivate.h"
#import "GPBUnknownFieldSet.h"
#import "GPBUnknownFields_PackagePrivate.h"
#define ASSERT_FIELD_TYPE(type) \
if (type_ != type) { \
@ -287,57 +289,90 @@
}
- (void)writeToOutput:(GPBCodedOutputStream *)output {
ASSERT_FIELD_TYPE(GPBUnknownFieldTypeLegacy);
NSUInteger count = storage_.legacy.mutableVarintList.count;
if (count > 0) {
[output writeUInt64Array:number_ values:storage_.legacy.mutableVarintList tag:0];
}
count = storage_.legacy.mutableFixed32List.count;
if (count > 0) {
[output writeFixed32Array:number_ values:storage_.legacy.mutableFixed32List tag:0];
}
count = storage_.legacy.mutableFixed64List.count;
if (count > 0) {
[output writeFixed64Array:number_ values:storage_.legacy.mutableFixed64List tag:0];
}
count = storage_.legacy.mutableLengthDelimitedList.count;
if (count > 0) {
[output writeBytesArray:number_ values:storage_.legacy.mutableLengthDelimitedList];
}
count = storage_.legacy.mutableGroupList.count;
if (count > 0) {
[output writeUnknownGroupArray:number_ values:storage_.legacy.mutableGroupList];
switch (type_) {
case GPBUnknownFieldTypeVarint:
[output writeUInt64:number_ value:storage_.intValue];
break;
case GPBUnknownFieldTypeFixed32:
[output writeFixed32:number_ value:(uint32_t)storage_.intValue];
break;
case GPBUnknownFieldTypeFixed64:
[output writeFixed64:number_ value:storage_.intValue];
break;
case GPBUnknownFieldTypeLengthDelimited:
[output writeBytes:number_ value:storage_.lengthDelimited];
break;
case GPBUnknownFieldTypeGroup:
[output writeRawVarint32:GPBWireFormatMakeTag(number_, GPBWireFormatStartGroup)];
[storage_.group writeToCodedOutputStream:output];
[output writeRawVarint32:GPBWireFormatMakeTag(number_, GPBWireFormatEndGroup)];
break;
case GPBUnknownFieldTypeLegacy: {
NSUInteger count = storage_.legacy.mutableVarintList.count;
if (count > 0) {
[output writeUInt64Array:number_ values:storage_.legacy.mutableVarintList tag:0];
}
count = storage_.legacy.mutableFixed32List.count;
if (count > 0) {
[output writeFixed32Array:number_ values:storage_.legacy.mutableFixed32List tag:0];
}
count = storage_.legacy.mutableFixed64List.count;
if (count > 0) {
[output writeFixed64Array:number_ values:storage_.legacy.mutableFixed64List tag:0];
}
count = storage_.legacy.mutableLengthDelimitedList.count;
if (count > 0) {
[output writeBytesArray:number_ values:storage_.legacy.mutableLengthDelimitedList];
}
count = storage_.legacy.mutableGroupList.count;
if (count > 0) {
[output writeUnknownGroupArray:number_ values:storage_.legacy.mutableGroupList];
}
}
}
}
- (size_t)serializedSize {
ASSERT_FIELD_TYPE(GPBUnknownFieldTypeLegacy);
__block size_t result = 0;
int32_t number = number_;
[storage_.legacy.mutableVarintList
enumerateValuesWithBlock:^(uint64_t value, __unused NSUInteger idx, __unused BOOL *stop) {
result += GPBComputeUInt64Size(number, value);
}];
[storage_.legacy.mutableFixed32List
enumerateValuesWithBlock:^(uint32_t value, __unused NSUInteger idx, __unused BOOL *stop) {
result += GPBComputeFixed32Size(number, value);
}];
[storage_.legacy.mutableFixed64List
enumerateValuesWithBlock:^(uint64_t value, __unused NSUInteger idx, __unused BOOL *stop) {
result += GPBComputeFixed64Size(number, value);
}];
switch (type_) {
case GPBUnknownFieldTypeVarint:
return GPBComputeUInt64Size(number_, storage_.intValue);
case GPBUnknownFieldTypeFixed32:
return GPBComputeFixed32Size(number_, (uint32_t)storage_.intValue);
case GPBUnknownFieldTypeFixed64:
return GPBComputeFixed64Size(number_, storage_.intValue);
case GPBUnknownFieldTypeLengthDelimited:
return GPBComputeBytesSize(number_, storage_.lengthDelimited);
case GPBUnknownFieldTypeGroup:
return (GPBComputeTagSize(number_) * 2) + [storage_.group serializedSize];
case GPBUnknownFieldTypeLegacy: {
__block size_t result = 0;
int32_t number = number_;
[storage_.legacy.mutableVarintList
enumerateValuesWithBlock:^(uint64_t value, __unused NSUInteger idx, __unused BOOL *stop) {
result += GPBComputeUInt64Size(number, value);
}];
for (NSData *data in storage_.legacy.mutableLengthDelimitedList) {
result += GPBComputeBytesSize(number, data);
}
[storage_.legacy.mutableFixed32List
enumerateValuesWithBlock:^(uint32_t value, __unused NSUInteger idx, __unused BOOL *stop) {
result += GPBComputeFixed32Size(number, value);
}];
for (GPBUnknownFieldSet *set in storage_.legacy.mutableGroupList) {
result += GPBComputeUnknownGroupSize(number, set);
}
[storage_.legacy.mutableFixed64List
enumerateValuesWithBlock:^(uint64_t value, __unused NSUInteger idx, __unused BOOL *stop) {
result += GPBComputeFixed64Size(number, value);
}];
return result;
for (NSData *data in storage_.legacy.mutableLengthDelimitedList) {
result += GPBComputeBytesSize(number, data);
}
for (GPBUnknownFieldSet *set in storage_.legacy.mutableGroupList) {
result += GPBComputeUnknownGroupSize(number, set);
}
return result;
}
}
}
- (void)writeAsMessageSetExtensionToOutput:(GPBCodedOutputStream *)output {

@ -6,6 +6,8 @@
// https://developers.google.com/open-source/licenses/bsd
#import "GPBUnknownFields.h"
#import "GPBCodedOutputStream.h"
#import "GPBCodedOutputStream_PackagePrivate.h"
#import "GPBUnknownField_PackagePrivate.h"
#define CHECK_FIELD_NUMBER(number) \
@ -137,6 +139,44 @@
return [fields_ countByEnumeratingWithState:state objects:stackbuf count:len];
}
#pragma mark - Internal Methods
- (size_t)serializedSize {
size_t result = 0;
for (GPBUnknownField *field in self->fields_) {
result += [field serializedSize];
}
return result;
}
- (void)writeToCodedOutputStream:(GPBCodedOutputStream *)output {
for (GPBUnknownField *field in fields_) {
[field writeToOutput:output];
}
}
- (NSData *)serializeAsData {
if (fields_.count == 0) {
return [NSData data];
}
size_t expectedSize = [self serializedSize];
NSMutableData *data = [NSMutableData dataWithLength:expectedSize];
GPBCodedOutputStream *stream = [[GPBCodedOutputStream alloc] initWithData:data];
@try {
[self writeToCodedOutputStream:stream];
[stream flush];
} @catch (NSException *exception) {
#if defined(DEBUG) && DEBUG
NSLog(@"Internal exception while building GPBUnknownFields serialized data: %@", exception);
#endif
}
#if defined(DEBUG) && DEBUG
NSAssert([stream bytesWritten] == expectedSize, @"Internal error within the library");
#endif
[stream release];
return data;
}
@end
@implementation GPBUnknownFields (AccessHelpers)

@ -0,0 +1,20 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2024 Google Inc. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd
#import <Foundation/Foundation.h>
#import "GPBUnknownFields.h"
@class GPBCodedOutputStream;
@interface GPBUnknownFields ()
- (size_t)serializedSize;
- (nonnull NSData *)serializeAsData;
- (void)writeToCodedOutputStream:(nonnull GPBCodedOutputStream *)output;
@end

@ -76,6 +76,7 @@
F43ADD432C2F381F005312E5 /* GPBCompileTest25.m in Sources */ = {isa = PBXBuildFile; fileRef = F43ADD422C2F381F005312E5 /* GPBCompileTest25.m */; };
F43ADD502C333D6C005312E5 /* GPBUnknownFields+Additions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F43ADD4F2C333D6B005312E5 /* GPBUnknownFields+Additions.swift */; };
F43ADD562C345CED005312E5 /* GPBUnknownField+Additions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F43ADD552C345CED005312E5 /* GPBUnknownField+Additions.swift */; };
F43ADD5C2C35A6CC005312E5 /* GPBUnknownFields_PackagePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = F43ADD5B2C35A6CC005312E5 /* GPBUnknownFields_PackagePrivate.h */; };
F43C88D0191D77FC009E917D /* text_format_unittest_data.txt in Resources */ = {isa = PBXBuildFile; fileRef = F43C88CF191D77FC009E917D /* text_format_unittest_data.txt */; };
F4487C4D1A9F8E0200531423 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; };
F4487C521A9F8E4D00531423 /* GPBProtocolBuffers.m in Sources */ = {isa = PBXBuildFile; fileRef = 8BCF338814ED799900BC5317 /* GPBProtocolBuffers.m */; };
@ -218,6 +219,7 @@
F43ADD422C2F381F005312E5 /* GPBCompileTest25.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBCompileTest25.m; sourceTree = "<group>"; };
F43ADD4F2C333D6B005312E5 /* GPBUnknownFields+Additions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "GPBUnknownFields+Additions.swift"; sourceTree = "<group>"; };
F43ADD552C345CED005312E5 /* GPBUnknownField+Additions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "GPBUnknownField+Additions.swift"; sourceTree = "<group>"; };
F43ADD5B2C35A6CC005312E5 /* GPBUnknownFields_PackagePrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPBUnknownFields_PackagePrivate.h; sourceTree = "<group>"; };
F43C88CF191D77FC009E917D /* text_format_unittest_data.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = text_format_unittest_data.txt; sourceTree = "<group>"; };
F4411BE71AF12FD700324B4A /* GPBArray_PackagePrivate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GPBArray_PackagePrivate.h; sourceTree = "<group>"; };
F4487C511A9F8E0200531423 /* libTestSingleSourceBuild.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libTestSingleSourceBuild.a; sourceTree = BUILT_PRODUCTS_DIR; };
@ -422,6 +424,7 @@
7461B4AE0F94F99000A0C422 /* GPBUnknownField.h */,
7461B4AF0F94F99000A0C422 /* GPBUnknownField.m */,
F43ADD552C345CED005312E5 /* GPBUnknownField+Additions.swift */,
F43ADD5B2C35A6CC005312E5 /* GPBUnknownFields_PackagePrivate.h */,
F43ADD2F2C2F2B91005312E5 /* GPBUnknownFields.h */,
F43ADD2E2C2F2B91005312E5 /* GPBUnknownFields.m */,
F43ADD4F2C333D6B005312E5 /* GPBUnknownFields+Additions.swift */,
@ -582,6 +585,7 @@
buildActionMask = 2147483647;
files = (
F43ADD312C2F2B91005312E5 /* GPBUnknownFields.h in Headers */,
F43ADD5C2C35A6CC005312E5 /* GPBUnknownFields_PackagePrivate.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};

@ -75,6 +75,7 @@
F43ADD472C2F387A005312E5 /* GPBCompileTest25.m in Sources */ = {isa = PBXBuildFile; fileRef = F43ADD462C2F387A005312E5 /* GPBCompileTest25.m */; };
F43ADD522C333E58005312E5 /* GPBUnknownFields+Additions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F43ADD512C333E58005312E5 /* GPBUnknownFields+Additions.swift */; };
F43ADD582C345D0D005312E5 /* GPBUnknownField+Additions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F43ADD572C345D0D005312E5 /* GPBUnknownField+Additions.swift */; };
F43ADD5E2C35A6E1005312E5 /* GPBUnknownFields_PackagePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = F43ADD5D2C35A6E1005312E5 /* GPBUnknownFields_PackagePrivate.h */; };
F43C88D0191D77FC009E917D /* text_format_unittest_data.txt in Resources */ = {isa = PBXBuildFile; fileRef = F43C88CF191D77FC009E917D /* text_format_unittest_data.txt */; };
F4487C6A1A9F8F8100531423 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; };
F4487C6F1A9F8FFF00531423 /* GPBProtocolBuffers.m in Sources */ = {isa = PBXBuildFile; fileRef = 8BCF338814ED799900BC5317 /* GPBProtocolBuffers.m */; };
@ -218,6 +219,7 @@
F43ADD462C2F387A005312E5 /* GPBCompileTest25.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBCompileTest25.m; sourceTree = "<group>"; };
F43ADD512C333E58005312E5 /* GPBUnknownFields+Additions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "GPBUnknownFields+Additions.swift"; sourceTree = "<group>"; };
F43ADD572C345D0D005312E5 /* GPBUnknownField+Additions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "GPBUnknownField+Additions.swift"; sourceTree = "<group>"; };
F43ADD5D2C35A6E1005312E5 /* GPBUnknownFields_PackagePrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPBUnknownFields_PackagePrivate.h; sourceTree = "<group>"; };
F43C88CF191D77FC009E917D /* text_format_unittest_data.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = text_format_unittest_data.txt; sourceTree = "<group>"; };
F4411BE81AF1301700324B4A /* GPBArray_PackagePrivate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GPBArray_PackagePrivate.h; sourceTree = "<group>"; };
F4487C6E1A9F8F8100531423 /* libTestSingleSourceBuild.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libTestSingleSourceBuild.a; sourceTree = BUILT_PRODUCTS_DIR; };
@ -427,6 +429,7 @@
7461B4AE0F94F99000A0C422 /* GPBUnknownField.h */,
7461B4AF0F94F99000A0C422 /* GPBUnknownField.m */,
F43ADD572C345D0D005312E5 /* GPBUnknownField+Additions.swift */,
F43ADD5D2C35A6E1005312E5 /* GPBUnknownFields_PackagePrivate.h */,
F43ADD372C2F2D06005312E5 /* GPBUnknownFields.h */,
F43ADD362C2F2D06005312E5 /* GPBUnknownFields.m */,
F43ADD512C333E58005312E5 /* GPBUnknownFields+Additions.swift */,
@ -586,6 +589,7 @@
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
F43ADD5E2C35A6E1005312E5 /* GPBUnknownFields_PackagePrivate.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};

@ -76,6 +76,7 @@
F43ADD492C2F389D005312E5 /* GPBCompileTest25.m in Sources */ = {isa = PBXBuildFile; fileRef = F43ADD482C2F389D005312E5 /* GPBCompileTest25.m */; };
F43ADD542C333EE5005312E5 /* GPBUnknownFields+Additions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F43ADD532C333EE5005312E5 /* GPBUnknownFields+Additions.swift */; };
F43ADD5A2C345D36005312E5 /* GPBUnknownField+Additions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F43ADD592C345D36005312E5 /* GPBUnknownField+Additions.swift */; };
F43ADD602C35A6F4005312E5 /* GPBUnknownFields_PackagePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = F43ADD5F2C35A6F4005312E5 /* GPBUnknownFields_PackagePrivate.h */; };
F43C88D0191D77FC009E917D /* text_format_unittest_data.txt in Resources */ = {isa = PBXBuildFile; fileRef = F43C88CF191D77FC009E917D /* text_format_unittest_data.txt */; };
F4487C6A1A9F8F8100531423 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; };
F4487C6F1A9F8FFF00531423 /* GPBProtocolBuffers.m in Sources */ = {isa = PBXBuildFile; fileRef = 8BCF338814ED799900BC5317 /* GPBProtocolBuffers.m */; };
@ -219,6 +220,7 @@
F43ADD482C2F389D005312E5 /* GPBCompileTest25.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBCompileTest25.m; sourceTree = "<group>"; };
F43ADD532C333EE5005312E5 /* GPBUnknownFields+Additions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "GPBUnknownFields+Additions.swift"; sourceTree = "<group>"; };
F43ADD592C345D36005312E5 /* GPBUnknownField+Additions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "GPBUnknownField+Additions.swift"; sourceTree = "<group>"; };
F43ADD5F2C35A6F4005312E5 /* GPBUnknownFields_PackagePrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPBUnknownFields_PackagePrivate.h; sourceTree = "<group>"; };
F43C88CF191D77FC009E917D /* text_format_unittest_data.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = text_format_unittest_data.txt; sourceTree = "<group>"; };
F4411BE81AF1301700324B4A /* GPBArray_PackagePrivate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GPBArray_PackagePrivate.h; sourceTree = "<group>"; };
F4487C6E1A9F8F8100531423 /* libTestSingleSourceBuild.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libTestSingleSourceBuild.a; sourceTree = BUILT_PRODUCTS_DIR; };
@ -428,6 +430,7 @@
7461B4AE0F94F99000A0C422 /* GPBUnknownField.h */,
7461B4AF0F94F99000A0C422 /* GPBUnknownField.m */,
F43ADD592C345D36005312E5 /* GPBUnknownField+Additions.swift */,
F43ADD5F2C35A6F4005312E5 /* GPBUnknownFields_PackagePrivate.h */,
F43ADD3C2C2F2D3D005312E5 /* GPBUnknownFields.h */,
F43ADD3B2C2F2D3D005312E5 /* GPBUnknownFields.m */,
F43ADD532C333EE5005312E5 /* GPBUnknownFields+Additions.swift */,
@ -588,6 +591,7 @@
buildActionMask = 2147483647;
files = (
F43ADD3E2C2F2D3D005312E5 /* GPBUnknownFields.h in Headers */,
F43ADD602C35A6F4005312E5 /* GPBUnknownFields_PackagePrivate.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};

@ -20,6 +20,22 @@ static inline NSData *DataFromCStr(const char *str) {
return [NSData dataWithBytes:str length:strlen(str)];
}
static inline NSData *_DataFromBytesInternal(int32_t unused, ...) {
NSMutableData *values = [NSMutableData dataWithCapacity:0];
va_list list;
va_start(list, unused);
int32_t n;
while ((n = va_arg(list, int32_t)) != 256) {
NSCAssert(n >= 0 && n < 256, @"Only 8 bit values");
uint8_t u = (uint8_t)n;
[values appendBytes:&u length:1];
}
va_end(list);
return values;
}
#define DataFromBytes(...) _DataFromBytesInternal(0, __VA_ARGS__, 256)
// Helper for uses of C arrays in tests cases.
#ifndef GPBARRAYSIZE
#define GPBARRAYSIZE(a) ((sizeof(a) / sizeof((a[0]))))

@ -5,9 +5,12 @@
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd
#import <Foundation/Foundation.h>
#import "GPBTestUtilities.h"
#import "GPBUnknownField.h"
#import "GPBUnknownFields.h"
#import "GPBUnknownFields_PackagePrivate.h"
#import "objectivec/Tests/Unittest.pbobjc.h"
@interface UnknownFieldsTest : GPBTestCase
@ -511,4 +514,66 @@
XCTAssertThrowsSpecificNamed([ufs fields:-1], NSException, NSInvalidArgumentException);
}
- (void)testSerialize {
// Don't need to test CodedOutputStream, just make sure things basically end up there.
{
GPBUnknownFields* ufs = [[[GPBUnknownFields alloc] init] autorelease];
XCTAssertEqualObjects([ufs serializeAsData], [NSData data]);
}
{
GPBUnknownFields* ufs = [[[GPBUnknownFields alloc] init] autorelease];
[ufs addFieldNumber:1 varint:1];
XCTAssertEqualObjects([ufs serializeAsData], DataFromBytes(0x08, 0x01));
}
{
GPBUnknownFields* ufs = [[[GPBUnknownFields alloc] init] autorelease];
[ufs addFieldNumber:1 fixed32:1];
XCTAssertEqualObjects([ufs serializeAsData], DataFromBytes(0x0d, 0x01, 0x00, 0x00, 0x00));
}
{
GPBUnknownFields* ufs = [[[GPBUnknownFields alloc] init] autorelease];
[ufs addFieldNumber:1 fixed64:1];
XCTAssertEqualObjects([ufs serializeAsData],
DataFromBytes(0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00));
}
{
GPBUnknownFields* ufs = [[[GPBUnknownFields alloc] init] autorelease];
[ufs addFieldNumber:1 lengthDelimited:DataFromCStr("foo")];
XCTAssertEqualObjects([ufs serializeAsData], DataFromBytes(0x0a, 0x03, 0x66, 0x6f, 0x6f));
}
{
GPBUnknownFields* ufs = [[[GPBUnknownFields alloc] init] autorelease];
[ufs addGroupWithFieldNumber:1]; // Empty group
XCTAssertEqualObjects([ufs serializeAsData], DataFromBytes(0x0b, 0x0c));
}
{
GPBUnknownFields* ufs = [[[GPBUnknownFields alloc] init] autorelease];
GPBUnknownFields* group = [ufs addGroupWithFieldNumber:1]; // With some fields
[group addFieldNumber:10 varint:10];
[group addFieldNumber:11 fixed32:32];
[group addFieldNumber:12 fixed32:32];
XCTAssertEqualObjects([ufs serializeAsData],
DataFromBytes(0x0b, 0x50, 0x0a, 0x5d, 0x20, 0x00, 0x00, 0x00, 0x65, 0x20,
0x00, 0x00, 0x00, 0x0c));
}
}
- (void)testMessageMergeUnknowns {
GPBUnknownFields* ufs = [[[GPBUnknownFields alloc] init] autorelease];
[ufs addFieldNumber:TestAllTypes_FieldNumber_OptionalInt64 varint:100];
[ufs addFieldNumber:TestAllTypes_FieldNumber_OptionalFixed32 fixed32:200];
[ufs addFieldNumber:TestAllTypes_FieldNumber_OptionalFixed64 fixed64:300];
[ufs addFieldNumber:TestAllTypes_FieldNumber_OptionalBytes lengthDelimited:DataFromCStr("foo")];
GPBUnknownFields* group = [ufs addGroupWithFieldNumber:TestAllTypes_FieldNumber_OptionalGroup];
[group addFieldNumber:TestAllTypes_OptionalGroup_FieldNumber_A varint:55];
TestAllTypes* msg = [TestAllTypes message];
[msg mergeUnknownFields:ufs extensionRegistry:nil];
XCTAssertEqual(msg.optionalInt64, 100);
XCTAssertEqual(msg.optionalFixed32, 200);
XCTAssertEqual(msg.optionalFixed64, 300);
XCTAssertEqualObjects(msg.optionalBytes, DataFromCStr("foo"));
XCTAssertEqual(msg.optionalGroup.a, 55);
}
@end

Loading…
Cancel
Save