blob: d6ef65908cd882970aa3acffd7548fea383ccff3 [file] [log] [blame]
// Protocol Buffers - Google's data interchange format
// Copyright 2008 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 "GPBUnknownField.h"
#import "GPBUnknownField_PackagePrivate.h"
#import "GPBCodedOutputStream.h"
#import "GPBCodedOutputStream_PackagePrivate.h"
#import "GPBUnknownFields.h"
#import "GPBUnknownFields_PackagePrivate.h"
#import "GPBWireFormat.h"
#define ASSERT_FIELD_TYPE(type) \
if (type_ != type) { \
[NSException raise:NSInternalInconsistencyException \
format:@"GPBUnknownField is the wrong type"]; \
}
@implementation GPBUnknownField
@synthesize number = number_;
@synthesize type = type_;
- (instancetype)initWithNumber:(int32_t)number varint:(uint64_t)varint {
if ((self = [super init])) {
number_ = number;
type_ = GPBUnknownFieldTypeVarint;
storage_.intValue = varint;
}
return self;
}
- (instancetype)initWithNumber:(int32_t)number fixed32:(uint32_t)fixed32 {
if ((self = [super init])) {
number_ = number;
type_ = GPBUnknownFieldTypeFixed32;
storage_.intValue = fixed32;
}
return self;
}
- (instancetype)initWithNumber:(int32_t)number fixed64:(uint64_t)fixed64 {
if ((self = [super init])) {
number_ = number;
type_ = GPBUnknownFieldTypeFixed64;
storage_.intValue = fixed64;
}
return self;
}
- (instancetype)initWithNumber:(int32_t)number lengthDelimited:(nonnull NSData *)data {
if ((self = [super init])) {
number_ = number;
type_ = GPBUnknownFieldTypeLengthDelimited;
storage_.lengthDelimited = [data copy];
}
return self;
}
- (instancetype)initWithNumber:(int32_t)number group:(nonnull GPBUnknownFields *)group {
if ((self = [super init])) {
number_ = number;
type_ = GPBUnknownFieldTypeGroup;
// Taking ownership of the group; so retain, not copy.
storage_.group = [group retain];
}
return self;
}
- (void)dealloc {
switch (type_) {
case GPBUnknownFieldTypeVarint:
case GPBUnknownFieldTypeFixed32:
case GPBUnknownFieldTypeFixed64:
break;
case GPBUnknownFieldTypeLengthDelimited:
[storage_.lengthDelimited release];
break;
case GPBUnknownFieldTypeGroup:
[storage_.group release];
break;
}
[super dealloc];
}
// Direct access is use for speed, to avoid even internally declaring things
// read/write, etc. The warning is enabled in the project to ensure code calling
// protos can turn on -Wdirect-ivar-access without issues.
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdirect-ivar-access"
- (uint64_t)varint {
ASSERT_FIELD_TYPE(GPBUnknownFieldTypeVarint);
return storage_.intValue;
}
- (uint32_t)fixed32 {
ASSERT_FIELD_TYPE(GPBUnknownFieldTypeFixed32);
return (uint32_t)storage_.intValue;
}
- (uint64_t)fixed64 {
ASSERT_FIELD_TYPE(GPBUnknownFieldTypeFixed64);
return storage_.intValue;
}
- (NSData *)lengthDelimited {
ASSERT_FIELD_TYPE(GPBUnknownFieldTypeLengthDelimited);
return storage_.lengthDelimited;
}
- (GPBUnknownFields *)group {
ASSERT_FIELD_TYPE(GPBUnknownFieldTypeGroup);
return storage_.group;
}
- (id)copyWithZone:(NSZone *)zone {
switch (type_) {
case GPBUnknownFieldTypeVarint:
case GPBUnknownFieldTypeFixed32:
case GPBUnknownFieldTypeFixed64:
case GPBUnknownFieldTypeLengthDelimited:
// In these modes, the object isn't mutable, so just return self.
return [self retain];
case GPBUnknownFieldTypeGroup: {
// The `GPBUnknownFields` for the group is mutable, so a new instance of this object and
// the group is needed.
GPBUnknownFields *copyGroup = [storage_.group copyWithZone:zone];
GPBUnknownField *copy = [[GPBUnknownField allocWithZone:zone] initWithNumber:number_
group:copyGroup];
[copyGroup release];
return copy;
}
}
}
- (BOOL)isEqual:(id)object {
if (self == object) return YES;
if (![object isKindOfClass:[GPBUnknownField class]]) return NO;
GPBUnknownField *field = (GPBUnknownField *)object;
if (number_ != field->number_) return NO;
if (type_ != field->type_) return NO;
switch (type_) {
case GPBUnknownFieldTypeVarint:
case GPBUnknownFieldTypeFixed32:
case GPBUnknownFieldTypeFixed64:
return storage_.intValue == field->storage_.intValue;
case GPBUnknownFieldTypeLengthDelimited:
return [storage_.lengthDelimited isEqual:field->storage_.lengthDelimited];
case GPBUnknownFieldTypeGroup:
return [storage_.group isEqual:field->storage_.group];
}
}
- (NSUInteger)hash {
const int prime = 31;
NSUInteger result = prime * number_ + type_;
switch (type_) {
case GPBUnknownFieldTypeVarint:
case GPBUnknownFieldTypeFixed32:
case GPBUnknownFieldTypeFixed64:
result = prime * result + (NSUInteger)storage_.intValue;
break;
case GPBUnknownFieldTypeLengthDelimited:
result = prime * result + [storage_.lengthDelimited hash];
break;
case GPBUnknownFieldTypeGroup:
result = prime * result + [storage_.group hash];
}
return result;
}
- (NSString *)description {
NSMutableString *description =
[NSMutableString stringWithFormat:@"<%@ %p>: Field: %d", [self class], self, number_];
switch (type_) {
case GPBUnknownFieldTypeVarint:
[description appendFormat:@" varint: %llu", storage_.intValue];
break;
case GPBUnknownFieldTypeFixed32:
[description appendFormat:@" fixed32: %u", (uint32_t)storage_.intValue];
break;
case GPBUnknownFieldTypeFixed64:
[description appendFormat:@" fixed64: %llu", storage_.intValue];
break;
case GPBUnknownFieldTypeLengthDelimited:
[description appendFormat:@" fixed64: %@", storage_.lengthDelimited];
break;
case GPBUnknownFieldTypeGroup:
[description appendFormat:@" group: %@", storage_.group];
break;
}
return description;
}
#pragma clang diagnostic pop
@end