Skip to content

Commit c5c9c89

Browse files
committed
[ObjC] Add apis for removing things from GPBUnknownFields.
PiperOrigin-RevId: 658538490
1 parent ed6dcd7 commit c5c9c89

File tree

3 files changed

+124
-0
lines changed

3 files changed

+124
-0
lines changed

objectivec/GPBUnknownFields.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,26 @@ __attribute__((objc_subclassing_restricted))
109109
**/
110110
- (nonnull GPBUnknownFields *)addGroupWithFieldNumber:(int32_t)fieldNumber;
111111

112+
/**
113+
* Removes the given field from the set.
114+
*
115+
* It is a programming error to attempt to remove a field that is not in this collection.
116+
*
117+
* Reminder: it is not save to mutate the collection while also using fast enumeration on it.
118+
*
119+
* @param field The field to remove.
120+
**/
121+
- (void)removeField:(nonnull GPBUnknownField *)field;
122+
123+
/**
124+
* Removes all of the fields from the collection that have the given field number.
125+
*
126+
* If there are no fields with the given field number, this is a no-op.
127+
*
128+
* @param fieldNumber The field number to remove.
129+
**/
130+
- (void)clearFieldNumber:(int32_t)fieldNumber;
131+
112132
@end
113133

114134
@interface GPBUnknownFields (AccessHelpers)

objectivec/GPBUnknownFields.m

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,34 @@ - (GPBUnknownFields *)addGroupWithFieldNumber:(int32_t)fieldNumber {
318318
return [group autorelease];
319319
}
320320

321+
- (void)removeField:(nonnull GPBUnknownField *)field {
322+
NSUInteger count = fields_.count;
323+
[fields_ removeObjectIdenticalTo:field];
324+
if (count == fields_.count) {
325+
[NSException raise:NSInvalidArgumentException format:@"The field was not present."];
326+
}
327+
}
328+
329+
- (void)clearFieldNumber:(int32_t)fieldNumber {
330+
CHECK_FIELD_NUMBER(fieldNumber);
331+
NSMutableIndexSet *toRemove = nil;
332+
NSUInteger idx = 0;
333+
for (GPBUnknownField *field in fields_) {
334+
if (field->number_ == fieldNumber) {
335+
if (toRemove == nil) {
336+
toRemove = [[NSMutableIndexSet alloc] initWithIndex:idx];
337+
} else {
338+
[toRemove addIndex:idx];
339+
}
340+
}
341+
++idx;
342+
}
343+
if (toRemove) {
344+
[fields_ removeObjectsAtIndexes:toRemove];
345+
[toRemove release];
346+
}
347+
}
348+
321349
#pragma mark - NSFastEnumeration protocol
322350

323351
- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state

objectivec/Tests/GPBUnknownFieldsTest.m

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -510,6 +510,82 @@ - (void)testGetFields {
510510
XCTAssertNil([ufs fields:99]); // Not present
511511
}
512512

513+
- (void)testRemoveField {
514+
GPBUnknownFields* ufs = [[[GPBUnknownFields alloc] init] autorelease];
515+
[ufs addFieldNumber:1 varint:1];
516+
[ufs addFieldNumber:1 fixed32:1];
517+
[ufs addFieldNumber:1 fixed64:1];
518+
XCTAssertEqual(ufs.count, 3);
519+
520+
NSArray<GPBUnknownField*>* fields = [ufs fields:1];
521+
XCTAssertEqual(fields.count, 3);
522+
GPBUnknownField* field = fields[0];
523+
XCTAssertEqual(field.number, 1);
524+
XCTAssertEqual(field.type, GPBUnknownFieldTypeVarint);
525+
XCTAssertEqual(field.varint, 1);
526+
[ufs removeField:field]; // Remove first (varint)
527+
XCTAssertEqual(ufs.count, 2);
528+
529+
fields = [ufs fields:1];
530+
XCTAssertEqual(fields.count, 2);
531+
field = fields[0];
532+
XCTAssertEqual(field.number, 1);
533+
XCTAssertEqual(field.type, GPBUnknownFieldTypeFixed32);
534+
field = fields[1];
535+
XCTAssertEqual(field.number, 1);
536+
XCTAssertEqual(field.type, GPBUnknownFieldTypeFixed64);
537+
[ufs removeField:field]; // Remove the second (fixed64)
538+
XCTAssertEqual(ufs.count, 1);
539+
540+
fields = [ufs fields:1];
541+
XCTAssertEqual(fields.count, 1);
542+
field = fields[0];
543+
XCTAssertEqual(field.number, 1);
544+
XCTAssertEqual(field.type, GPBUnknownFieldTypeFixed32);
545+
546+
field = [[field retain] autorelease]; // Hold on to this last one.
547+
[ufs removeField:field]; // Remove the last one (fixed32)
548+
XCTAssertEqual(ufs.count, 0);
549+
550+
// Trying to remove something not in the set should fail.
551+
XCTAssertThrowsSpecificNamed([ufs removeField:field], NSException, NSInvalidArgumentException);
552+
}
553+
554+
- (void)testClearFieldNumber {
555+
GPBUnknownFields* ufs = [[[GPBUnknownFields alloc] init] autorelease];
556+
[ufs addFieldNumber:1 varint:1];
557+
[ufs addFieldNumber:2 fixed32:2];
558+
[ufs addFieldNumber:1 fixed64:1];
559+
[ufs addFieldNumber:3 varint:3];
560+
XCTAssertEqual(ufs.count, 4);
561+
562+
[ufs clearFieldNumber:999]; // Not present, noop.
563+
XCTAssertEqual(ufs.count, 4);
564+
565+
[ufs clearFieldNumber:1]; // Should remove slot zero and slot two.
566+
XCTAssertEqual(ufs.count, 2);
567+
NSArray<GPBUnknownField*>* fields = [ufs fields:2];
568+
XCTAssertEqual(fields.count, 1);
569+
GPBUnknownField* field = fields[0];
570+
XCTAssertEqual(field.number, 2);
571+
XCTAssertEqual(field.type, GPBUnknownFieldTypeFixed32);
572+
XCTAssertEqual(field.fixed32, 2);
573+
fields = [ufs fields:3];
574+
XCTAssertEqual(fields.count, 1);
575+
field = fields[0];
576+
XCTAssertEqual(field.number, 3);
577+
XCTAssertEqual(field.type, GPBUnknownFieldTypeVarint);
578+
XCTAssertEqual(field.varint, 3);
579+
580+
[ufs clearFieldNumber:2]; // Should remove slot one.
581+
fields = [ufs fields:3];
582+
XCTAssertEqual(fields.count, 1);
583+
field = fields[0];
584+
XCTAssertEqual(field.number, 3);
585+
XCTAssertEqual(field.type, GPBUnknownFieldTypeVarint);
586+
XCTAssertEqual(field.varint, 3);
587+
}
588+
513589
- (void)testFastEnumeration {
514590
GPBUnknownFields* ufs = [[[GPBUnknownFields alloc] init] autorelease];
515591
[ufs addFieldNumber:1 varint:1];

0 commit comments

Comments
 (0)