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
		
	
	
	
		
			Matlab
		
	
		
		
			
		
	
	
			238 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			Matlab
		
	
| 
											12 years ago
										 | // 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 |