mirror of https://github.com/oxen-io/session-ios
				
				
				
			
			You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			238 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			Objective-C
		
	
			
		
		
	
	
			238 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			Objective-C
		
	
| // Copyright 2008 Cyrus Najmabadi
 | |
| //
 | |
| // Licensed under the Apache License, Version 2.0 (the "License");
 | |
| // you may not use this file except in compliance with the License.
 | |
| // You may obtain a copy of the License at
 | |
| //
 | |
| //     http://www.apache.org/licenses/LICENSE-2.0
 | |
| //
 | |
| // Unless required by applicable law or agreed to in writing, software
 | |
| // distributed under the License is distributed on an "AS IS" BASIS,
 | |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | |
| // See the License for the specific language governing permissions and
 | |
| // limitations under the License.
 | |
| 
 | |
| #import "UnknownFieldSet_Builder.h"
 | |
| 
 | |
| #import "CodedInputStream.h"
 | |
| #import "Field.h"
 | |
| #import "MutableField.h"
 | |
| #import "UnknownFieldSet.h"
 | |
| #import "WireFormat.h"
 | |
| 
 | |
| @interface PBUnknownFieldSet_Builder ()
 | |
| @property (retain) NSMutableDictionary* fields;
 | |
| @property int32_t lastFieldNumber;
 | |
| @property (retain) PBMutableField* lastField;
 | |
| @end
 | |
| 
 | |
| 
 | |
| @implementation PBUnknownFieldSet_Builder
 | |
| 
 | |
| @synthesize fields;
 | |
| @synthesize lastFieldNumber;
 | |
| @synthesize lastField;
 | |
| 
 | |
| 
 | |
| - (void) dealloc {
 | |
|   self.fields = nil;
 | |
|   self.lastFieldNumber = 0;
 | |
|   self.lastField = nil;
 | |
| }
 | |
| 
 | |
| 
 | |
| - (id) init {
 | |
|   if ((self = [super init])) {
 | |
|     self.fields = [NSMutableDictionary dictionary];
 | |
|   }
 | |
|   return self;
 | |
| }
 | |
| 
 | |
| 
 | |
| + (PBUnknownFieldSet_Builder*) newBuilder:(PBUnknownFieldSet*) unknownFields {
 | |
|   PBUnknownFieldSet_Builder* builder = [[PBUnknownFieldSet_Builder alloc] init];
 | |
|   [builder mergeUnknownFields:unknownFields];
 | |
|   return builder;
 | |
| }
 | |
| 
 | |
| 
 | |
| /**
 | |
|  * Add a field to the {@code PBUnknownFieldSet}.  If a field with the same
 | |
|  * number already exists, it is removed.
 | |
|  */
 | |
| - (PBUnknownFieldSet_Builder*) addField:(PBField*) field forNumber:(int32_t) number {
 | |
|   if (number == 0) {
 | |
|     @throw [NSException exceptionWithName:@"IllegalArgument" reason:@"" userInfo:nil];
 | |
|   }
 | |
|   if (lastField != nil && lastFieldNumber == number) {
 | |
|     // Discard this.
 | |
|     self.lastField = nil;
 | |
|     lastFieldNumber = 0;
 | |
|   }
 | |
|   [fields setObject:field forKey:[NSNumber numberWithInt:number]];
 | |
|   return self;
 | |
| }
 | |
| 
 | |
| 
 | |
| /**
 | |
|  * Get a field builder for the given field number which includes any
 | |
|  * values that already exist.
 | |
|  */
 | |
| - (PBMutableField*) getFieldBuilder:(int32_t) number {
 | |
|   if (lastField != nil) {
 | |
|     if (number == lastFieldNumber) {
 | |
|       return lastField;
 | |
|     }
 | |
|     // Note:  addField() will reset lastField and lastFieldNumber.
 | |
|     [self addField:lastField forNumber:lastFieldNumber];
 | |
|   }
 | |
|   if (number == 0) {
 | |
|     return nil;
 | |
|   } else {
 | |
|     PBField* existing = [fields objectForKey:[NSNumber numberWithInt:number]];
 | |
|     lastFieldNumber = number;
 | |
|     self.lastField = [PBMutableField field];
 | |
|     if (existing != nil) {
 | |
|       [lastField mergeFromField:existing];
 | |
|     }
 | |
|     return lastField;
 | |
|   }
 | |
| }
 | |
| 
 | |
| 
 | |
| - (PBUnknownFieldSet*) build {
 | |
|   [self getFieldBuilder:0];  // Force lastField to be built.
 | |
|   PBUnknownFieldSet* result;
 | |
|   if (fields.count == 0) {
 | |
|     result = [PBUnknownFieldSet defaultInstance];
 | |
|   } else {
 | |
|     result = [PBUnknownFieldSet setWithFields:fields];
 | |
|   }
 | |
|   self.fields = nil;
 | |
|   return result;
 | |
| }
 | |
| 
 | |
| 
 | |
| /** Check if the given field number is present in the set. */
 | |
| - (BOOL) hasField:(int32_t) number {
 | |
|   if (number == 0) {
 | |
|     @throw [NSException exceptionWithName:@"IllegalArgument" reason:@"" userInfo:nil];
 | |
|   }
 | |
| 
 | |
|   return number == lastFieldNumber || ([fields objectForKey:[NSNumber numberWithInt:number]] != nil);
 | |
| }
 | |
| 
 | |
| 
 | |
| /**
 | |
|  * Add a field to the {@code PBUnknownFieldSet}.  If a field with the same
 | |
|  * number already exists, the two are merged.
 | |
|  */
 | |
| - (PBUnknownFieldSet_Builder*) mergeField:(PBField*) field forNumber:(int32_t) number {
 | |
|   if (number == 0) {
 | |
|     @throw [NSException exceptionWithName:@"IllegalArgument" reason:@"" userInfo:nil];
 | |
|   }
 | |
|   if ([self hasField:number]) {
 | |
|     [[self getFieldBuilder:number] mergeFromField:field];
 | |
|   } else {
 | |
|     // Optimization:  We could call getFieldBuilder(number).mergeFrom(field)
 | |
|     // in this case, but that would create a copy of the PBField object.
 | |
|     // We'd rather reuse the one passed to us, so call addField() instead.
 | |
|     [self addField:field forNumber:number];
 | |
|   }
 | |
| 
 | |
|   return self;
 | |
| }
 | |
| 
 | |
| 
 | |
| - (PBUnknownFieldSet_Builder*) mergeUnknownFields:(PBUnknownFieldSet*) other {
 | |
|   if (other != [PBUnknownFieldSet defaultInstance]) {
 | |
|     for (NSNumber* number in other.fields) {
 | |
|       PBField* field = [other.fields objectForKey:number];
 | |
|       [self mergeField:field forNumber:[number intValue]];
 | |
|     }
 | |
|   }
 | |
|   return self;
 | |
| }
 | |
| 
 | |
| 
 | |
| - (PBUnknownFieldSet_Builder*) mergeFromData:(NSData*) data {
 | |
|   PBCodedInputStream* input = [PBCodedInputStream streamWithData:data];
 | |
|   [self mergeFromCodedInputStream:input];
 | |
|   [input checkLastTagWas:0];
 | |
|   return self;
 | |
| }
 | |
| 
 | |
| 
 | |
| - (PBUnknownFieldSet_Builder*) mergeFromInputStream:(NSInputStream*) input {
 | |
|   @throw [NSException exceptionWithName:@"" reason:@"" userInfo:nil];
 | |
| }
 | |
| 
 | |
| 
 | |
| - (PBUnknownFieldSet_Builder*) mergeVarintField:(int32_t) number value:(int32_t) value {
 | |
|   if (number == 0) {
 | |
|     @throw [NSException exceptionWithName:@"IllegalArgument" reason:@"Zero is not a valid field number." userInfo:nil];
 | |
|   }
 | |
| 
 | |
|   [[self getFieldBuilder:number] addVarint:value];
 | |
|   return self;
 | |
| }
 | |
| 
 | |
| 
 | |
| /**
 | |
|  * Parse a single field from {@code input} and merge it into this set.
 | |
|  * @param tag The field's tag number, which was already parsed.
 | |
|  * @return {@code NO} if the tag is an engroup tag.
 | |
|  */
 | |
| - (BOOL) mergeFieldFrom:(int32_t) tag input:(PBCodedInputStream*) input {
 | |
|   int32_t number = PBWireFormatGetTagFieldNumber(tag);
 | |
|   switch (PBWireFormatGetTagWireType(tag)) {
 | |
|     case PBWireFormatVarint:
 | |
|       [[self getFieldBuilder:number] addVarint:[input readInt64]];
 | |
|       return YES;
 | |
|     case PBWireFormatFixed64:
 | |
|       [[self getFieldBuilder:number] addFixed64:[input readFixed64]];
 | |
|       return YES;
 | |
|     case PBWireFormatLengthDelimited:
 | |
|       [[self getFieldBuilder:number] addLengthDelimited:[input readData]];
 | |
|       return YES;
 | |
|     case PBWireFormatStartGroup: {
 | |
|       PBUnknownFieldSet_Builder* subBuilder = [PBUnknownFieldSet builder];
 | |
|       [input readUnknownGroup:number builder:subBuilder];
 | |
|       [[self getFieldBuilder:number] addGroup:[subBuilder build]];
 | |
|       return YES;
 | |
|     }
 | |
|     case PBWireFormatEndGroup:
 | |
|       return NO;
 | |
|     case PBWireFormatFixed32:
 | |
|       [[self getFieldBuilder:number] addFixed32:[input readFixed32]];
 | |
|       return YES;
 | |
|     default:
 | |
|       @throw [NSException exceptionWithName:@"InvalidProtocolBuffer" reason:@"" userInfo:nil];
 | |
|   }
 | |
| }
 | |
| 
 | |
| 
 | |
| /**
 | |
|  * Parse an entire message from {@code input} and merge its fields into
 | |
|  * this set.
 | |
|  */
 | |
| - (PBUnknownFieldSet_Builder*) mergeFromCodedInputStream:(PBCodedInputStream*) input {
 | |
|   while (YES) {
 | |
|     int32_t tag = [input readTag];
 | |
|     if (tag == 0 || ![self mergeFieldFrom:tag input:input]) {
 | |
|       break;
 | |
|     }
 | |
|   }
 | |
|   return self;
 | |
| }
 | |
| 
 | |
| 
 | |
| - (PBUnknownFieldSet_Builder*) clear {
 | |
|   self.fields = [NSMutableDictionary dictionary];
 | |
|   self.lastFieldNumber = 0;
 | |
|   self.lastField = nil;
 | |
|   return self;
 | |
| }
 | |
| 
 | |
| @end
 |