Merging UI code with some basic TextSecureKit code.
|
@ -1,27 +0,0 @@
|
|||
// 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 "Message.h"
|
||||
|
||||
/**
|
||||
* A partial implementation of the {@link Message} interface which implements
|
||||
* as many methods of that interface as possible in terms of other methods.
|
||||
*
|
||||
* @author Cyrus Najmabadi
|
||||
*/
|
||||
@interface PBAbstractMessage : NSObject<PBMessage> {
|
||||
@private
|
||||
}
|
||||
|
||||
@end
|
|
@ -1,74 +0,0 @@
|
|||
// 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 "AbstractMessage.h"
|
||||
|
||||
#import "CodedOutputStream.h"
|
||||
|
||||
@implementation PBAbstractMessage
|
||||
|
||||
- (id) init {
|
||||
if ((self = [super init])) {
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
- (NSData*) data {
|
||||
NSMutableData* data = [NSMutableData dataWithLength:(NSUInteger)self.serializedSize];
|
||||
PBCodedOutputStream* stream = [PBCodedOutputStream streamWithData:data];
|
||||
[self writeToCodedOutputStream:stream];
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
- (BOOL) isInitialized {
|
||||
@throw [NSException exceptionWithName:@"ImproperSubclassing" reason:@"" userInfo:nil];
|
||||
}
|
||||
|
||||
|
||||
- (int32_t) serializedSize {
|
||||
@throw [NSException exceptionWithName:@"ImproperSubclassing" reason:@"" userInfo:nil];
|
||||
}
|
||||
|
||||
|
||||
- (void) writeToCodedOutputStream:(PBCodedOutputStream*) output {
|
||||
@throw [NSException exceptionWithName:@"ImproperSubclassing" reason:@"" userInfo:nil];
|
||||
}
|
||||
|
||||
|
||||
- (void) writeToOutputStream:(NSOutputStream*) output {
|
||||
PBCodedOutputStream* codedOutput = [PBCodedOutputStream streamWithOutputStream:output];
|
||||
[self writeToCodedOutputStream:codedOutput];
|
||||
[codedOutput flush];
|
||||
}
|
||||
|
||||
|
||||
- (id<PBMessage>) defaultInstance {
|
||||
@throw [NSException exceptionWithName:@"ImproperSubclassing" reason:@"" userInfo:nil];
|
||||
}
|
||||
|
||||
|
||||
- (PBUnknownFieldSet*) unknownFields {
|
||||
@throw [NSException exceptionWithName:@"ImproperSubclassing" reason:@"" userInfo:nil];
|
||||
}
|
||||
|
||||
|
||||
- (id<PBMessage_Builder>) builder {
|
||||
@throw [NSException exceptionWithName:@"ImproperSubclassing" reason:@"" userInfo:nil];
|
||||
}
|
||||
|
||||
|
||||
@end
|
|
@ -1,25 +0,0 @@
|
|||
// 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 "Message_Builder.h"
|
||||
|
||||
/**
|
||||
* A partial implementation of the {@link Message.Builder} interface which
|
||||
* implements as many methods of that interface as possible in terms of
|
||||
* other methods.
|
||||
*/
|
||||
@interface PBAbstractMessage_Builder : NSObject<PBMessage_Builder> {
|
||||
}
|
||||
|
||||
@end
|
|
@ -1,119 +0,0 @@
|
|||
// 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 "AbstractMessage_Builder.h"
|
||||
|
||||
#import "CodedInputStream.h"
|
||||
#import "ExtensionRegistry.h"
|
||||
#import "UnknownFieldSet.h"
|
||||
#import "UnknownFieldSet_Builder.h"
|
||||
|
||||
|
||||
@implementation PBAbstractMessage_Builder
|
||||
|
||||
- (id<PBMessage_Builder>) clone {
|
||||
@throw [NSException exceptionWithName:@"ImproperSubclassing" reason:@"" userInfo:nil];
|
||||
}
|
||||
|
||||
|
||||
- (id<PBMessage_Builder>) clear {
|
||||
@throw [NSException exceptionWithName:@"ImproperSubclassing" reason:@"" userInfo:nil];
|
||||
}
|
||||
|
||||
|
||||
- (id<PBMessage_Builder>) mergeFromCodedInputStream:(PBCodedInputStream*) input {
|
||||
return [self mergeFromCodedInputStream:input extensionRegistry:[PBExtensionRegistry emptyRegistry]];
|
||||
}
|
||||
|
||||
|
||||
- (id<PBMessage_Builder>) mergeFromCodedInputStream:(PBCodedInputStream*) input
|
||||
extensionRegistry:(PBExtensionRegistry*) extensionRegistry {
|
||||
@throw [NSException exceptionWithName:@"ImproperSubclassing" reason:@"" userInfo:nil];
|
||||
}
|
||||
|
||||
|
||||
- (id<PBMessage_Builder>) mergeUnknownFields:(PBUnknownFieldSet*) unknownFields {
|
||||
PBUnknownFieldSet* merged =
|
||||
[[[PBUnknownFieldSet builderWithUnknownFields:self.unknownFields]
|
||||
mergeUnknownFields:unknownFields] build];
|
||||
|
||||
[self setUnknownFields:merged];
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
- (id<PBMessage_Builder>) mergeFromData:(NSData*) data {
|
||||
PBCodedInputStream* input = [PBCodedInputStream streamWithData:data];
|
||||
[self mergeFromCodedInputStream:input];
|
||||
[input checkLastTagWas:0];
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
- (id<PBMessage_Builder>) mergeFromData:(NSData*) data
|
||||
extensionRegistry:(PBExtensionRegistry*) extensionRegistry {
|
||||
PBCodedInputStream* input = [PBCodedInputStream streamWithData:data];
|
||||
[self mergeFromCodedInputStream:input extensionRegistry:extensionRegistry];
|
||||
[input checkLastTagWas:0];
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
- (id<PBMessage_Builder>) mergeFromInputStream:(NSInputStream*) input {
|
||||
PBCodedInputStream* codedInput = [PBCodedInputStream streamWithInputStream:input];
|
||||
[self mergeFromCodedInputStream:codedInput];
|
||||
[codedInput checkLastTagWas:0];
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
- (id<PBMessage_Builder>) mergeFromInputStream:(NSInputStream*) input
|
||||
extensionRegistry:(PBExtensionRegistry*) extensionRegistry {
|
||||
PBCodedInputStream* codedInput = [PBCodedInputStream streamWithInputStream:input];
|
||||
[self mergeFromCodedInputStream:codedInput extensionRegistry:extensionRegistry];
|
||||
[codedInput checkLastTagWas:0];
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
- (id<PBMessage>) build {
|
||||
@throw [NSException exceptionWithName:@"ImproperSubclassing" reason:@"" userInfo:nil];
|
||||
}
|
||||
|
||||
|
||||
- (id<PBMessage>) buildPartial {
|
||||
@throw [NSException exceptionWithName:@"ImproperSubclassing" reason:@"" userInfo:nil];
|
||||
}
|
||||
|
||||
|
||||
- (BOOL) isInitialized {
|
||||
@throw [NSException exceptionWithName:@"ImproperSubclassing" reason:@"" userInfo:nil];
|
||||
}
|
||||
|
||||
|
||||
- (id<PBMessage>) defaultInstance {
|
||||
@throw [NSException exceptionWithName:@"ImproperSubclassing" reason:@"" userInfo:nil];
|
||||
}
|
||||
|
||||
|
||||
- (PBUnknownFieldSet*) unknownFields {
|
||||
@throw [NSException exceptionWithName:@"ImproperSubclassing" reason:@"" userInfo:nil];
|
||||
}
|
||||
|
||||
|
||||
- (id<PBMessage_Builder>) setUnknownFields:(PBUnknownFieldSet*) unknownFields {
|
||||
@throw [NSException exceptionWithName:@"ImproperSubclassing" reason:@"" userInfo:nil];
|
||||
}
|
||||
|
||||
@end
|
|
@ -1,27 +0,0 @@
|
|||
// 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 "ForwardDeclarations.h"
|
||||
|
||||
#import "CodedInputStream.h"
|
||||
#import "CodedOutputStream.h"
|
||||
#import "ExtendableMessage.h"
|
||||
#import "ExtendableMessage_Builder.h"
|
||||
#import "ExtensionRegistry.h"
|
||||
#import "GeneratedMessage.h"
|
||||
#import "GeneratedMessage_Builder.h"
|
||||
#import "Message_Builder.h"
|
||||
#import "UnknownFieldSet.h"
|
||||
#import "UnknownFieldSet_Builder.h"
|
||||
#import "Utilities.h"
|
|
@ -1,184 +0,0 @@
|
|||
// 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.
|
||||
|
||||
@class PBExtensionRegistry;
|
||||
@class PBUnknownFieldSet_Builder;
|
||||
@protocol PBMessage_Builder;
|
||||
|
||||
/**
|
||||
* Reads and decodes protocol message fields.
|
||||
*
|
||||
* This class contains two kinds of methods: methods that read specific
|
||||
* protocol message constructs and field types (e.g. {@link #readTag()} and
|
||||
* {@link #readInt32()}) and methods that read low-level values (e.g.
|
||||
* {@link #readRawVarint32()} and {@link #readRawBytes}). If you are reading
|
||||
* encoded protocol messages, you should use the former methods, but if you are
|
||||
* reading some other format of your own design, use the latter.
|
||||
*
|
||||
* @author Cyrus Najmabadi
|
||||
*/
|
||||
@interface PBCodedInputStream : NSObject {
|
||||
@private
|
||||
NSMutableData* buffer;
|
||||
int32_t bufferSize;
|
||||
int32_t bufferSizeAfterLimit;
|
||||
int32_t bufferPos;
|
||||
NSInputStream* input;
|
||||
int32_t lastTag;
|
||||
|
||||
/**
|
||||
* The total number of bytes read before the current buffer. The total
|
||||
* bytes read up to the current position can be computed as
|
||||
* {@code totalBytesRetired + bufferPos}.
|
||||
*/
|
||||
int32_t totalBytesRetired;
|
||||
|
||||
/** The absolute position of the end of the current message. */
|
||||
int32_t currentLimit;
|
||||
|
||||
/** See setRecursionLimit() */
|
||||
int32_t recursionDepth;
|
||||
int32_t recursionLimit;
|
||||
|
||||
/** See setSizeLimit() */
|
||||
int32_t sizeLimit;
|
||||
}
|
||||
|
||||
+ (PBCodedInputStream*) streamWithData:(NSData*) data;
|
||||
+ (PBCodedInputStream*) streamWithInputStream:(NSInputStream*) input;
|
||||
|
||||
/**
|
||||
* Attempt to read a field tag, returning zero if we have reached EOF.
|
||||
* Protocol message parsers use this to read tags, since a protocol message
|
||||
* may legally end wherever a tag occurs, and zero is not a valid tag number.
|
||||
*/
|
||||
- (int32_t) readTag;
|
||||
- (BOOL) refillBuffer:(BOOL) mustSucceed;
|
||||
|
||||
- (Float64) readDouble;
|
||||
- (Float32) readFloat;
|
||||
- (int64_t) readUInt64;
|
||||
- (int32_t) readUInt32;
|
||||
- (int64_t) readInt64;
|
||||
- (int32_t) readInt32;
|
||||
- (int64_t) readFixed64;
|
||||
- (int32_t) readFixed32;
|
||||
- (int32_t) readEnum;
|
||||
- (int32_t) readSFixed32;
|
||||
- (int64_t) readSFixed64;
|
||||
- (int32_t) readSInt32;
|
||||
- (int64_t) readSInt64;
|
||||
|
||||
/**
|
||||
* Read one byte from the input.
|
||||
*
|
||||
* @throws InvalidProtocolBuffer The end of the stream or the current
|
||||
* limit was reached.
|
||||
*/
|
||||
- (int8_t) readRawByte;
|
||||
|
||||
/**
|
||||
* Read a raw Varint from the stream. If larger than 32 bits, discard the
|
||||
* upper bits.
|
||||
*/
|
||||
- (int32_t) readRawVarint32;
|
||||
- (int64_t) readRawVarint64;
|
||||
- (int32_t) readRawLittleEndian32;
|
||||
- (int64_t) readRawLittleEndian64;
|
||||
|
||||
/**
|
||||
* Read a fixed size of bytes from the input.
|
||||
*
|
||||
* @throws InvalidProtocolBuffer The end of the stream or the current
|
||||
* limit was reached.
|
||||
*/
|
||||
- (NSData*) readRawData:(int32_t) size;
|
||||
|
||||
/**
|
||||
* Reads and discards a single field, given its tag value.
|
||||
*
|
||||
* @return {@code false} if the tag is an endgroup tag, in which case
|
||||
* nothing is skipped. Otherwise, returns {@code true}.
|
||||
*/
|
||||
- (BOOL) skipField:(int32_t) tag;
|
||||
|
||||
|
||||
/**
|
||||
* Reads and discards {@code size} bytes.
|
||||
*
|
||||
* @throws InvalidProtocolBuffer The end of the stream or the current
|
||||
* limit was reached.
|
||||
*/
|
||||
- (void) skipRawData:(int32_t) size;
|
||||
|
||||
/**
|
||||
* Reads and discards an entire message. This will read either until EOF
|
||||
* or until an endgroup tag, whichever comes first.
|
||||
*/
|
||||
- (void) skipMessage;
|
||||
|
||||
- (BOOL) isAtEnd;
|
||||
- (int32_t) pushLimit:(int32_t) byteLimit;
|
||||
- (void) recomputeBufferSizeAfterLimit;
|
||||
- (void) popLimit:(int32_t) oldLimit;
|
||||
- (int32_t) bytesUntilLimit;
|
||||
|
||||
/**
|
||||
* Decode a ZigZag-encoded 32-bit value. ZigZag encodes signed integers
|
||||
* into values that can be efficiently encoded with varint. (Otherwise,
|
||||
* negative values must be sign-extended to 64 bits to be varint encoded,
|
||||
* thus always taking 10 bytes on the wire.)
|
||||
*
|
||||
* @param n An unsigned 32-bit integer, stored in a signed int.
|
||||
* @return A signed 32-bit integer.
|
||||
*/
|
||||
int32_t decodeZigZag32(int32_t n);
|
||||
|
||||
/**
|
||||
* Decode a ZigZag-encoded 64-bit value. ZigZag encodes signed integers
|
||||
* into values that can be efficiently encoded with varint. (Otherwise,
|
||||
* negative values must be sign-extended to 64 bits to be varint encoded,
|
||||
* thus always taking 10 bytes on the wire.)
|
||||
*
|
||||
* @param n An unsigned 64-bit integer, stored in a signed int.
|
||||
* @return A signed 64-bit integer.
|
||||
*/
|
||||
int64_t decodeZigZag64(int64_t n);
|
||||
|
||||
/** Read an embedded message field value from the stream. */
|
||||
- (void) readMessage:(id<PBMessage_Builder>) builder extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
|
||||
|
||||
- (BOOL) readBool;
|
||||
- (NSString*) readString;
|
||||
- (NSData*) readData;
|
||||
|
||||
- (void) readGroup:(int32_t) fieldNumber builder:(id<PBMessage_Builder>) builder extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
|
||||
|
||||
/**
|
||||
* Reads a {@code group} field value from the stream and merges it into the
|
||||
* given {@link UnknownFieldSet}.
|
||||
*/
|
||||
- (void) readUnknownGroup:(int32_t) fieldNumber builder:(PBUnknownFieldSet_Builder*) builder;
|
||||
|
||||
/**
|
||||
* Verifies that the last call to readTag() returned the given tag value.
|
||||
* This is used to verify that a nested group ended with the correct
|
||||
* end tag.
|
||||
*
|
||||
* @throws InvalidProtocolBuffer {@code value} does not match the
|
||||
* last tag.
|
||||
*/
|
||||
- (void) checkLastTagWas:(int32_t) value;
|
||||
|
||||
@end
|
|
@ -1,790 +0,0 @@
|
|||
// 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 "CodedInputStream.h"
|
||||
|
||||
#import "Message_Builder.h"
|
||||
#import "Utilities.h"
|
||||
#import "WireFormat.h"
|
||||
#import "UnknownFieldSet_Builder.h"
|
||||
|
||||
@interface PBCodedInputStream ()
|
||||
@property (retain) NSMutableData* buffer;
|
||||
@property (retain) NSInputStream* input;
|
||||
@end
|
||||
|
||||
|
||||
@implementation PBCodedInputStream
|
||||
|
||||
const int32_t DEFAULT_RECURSION_LIMIT = 64;
|
||||
const int32_t DEFAULT_SIZE_LIMIT = 64 << 20; // 64MB
|
||||
const int32_t BUFFER_SIZE = 4096;
|
||||
|
||||
@synthesize buffer;
|
||||
@synthesize input;
|
||||
|
||||
- (void) dealloc {
|
||||
[input close];
|
||||
self.buffer = nil;
|
||||
self.input = nil;
|
||||
}
|
||||
|
||||
|
||||
- (void) commonInit {
|
||||
currentLimit = INT_MAX;
|
||||
recursionLimit = DEFAULT_RECURSION_LIMIT;
|
||||
sizeLimit = DEFAULT_SIZE_LIMIT;
|
||||
}
|
||||
|
||||
|
||||
- (id) initWithData:(NSData*) data {
|
||||
if ((self = [super init])) {
|
||||
self.buffer = [NSMutableData dataWithData:data];
|
||||
bufferSize = (int32_t)buffer.length;
|
||||
self.input = nil;
|
||||
[self commonInit];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
- (id) initWithInputStream:(NSInputStream*) input_ {
|
||||
if ((self = [super init])) {
|
||||
self.buffer = [NSMutableData dataWithLength:BUFFER_SIZE];
|
||||
bufferSize = 0;
|
||||
self.input = input_;
|
||||
[input open];
|
||||
[self commonInit];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
+ (PBCodedInputStream*) streamWithData:(NSData*) data {
|
||||
return [[PBCodedInputStream alloc] initWithData:data];
|
||||
}
|
||||
|
||||
|
||||
+ (PBCodedInputStream*) streamWithInputStream:(NSInputStream*) input {
|
||||
return [[PBCodedInputStream alloc] initWithInputStream:input];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Attempt to read a field tag, returning zero if we have reached EOF.
|
||||
* Protocol message parsers use this to read tags, since a protocol message
|
||||
* may legally end wherever a tag occurs, and zero is not a valid tag number.
|
||||
*/
|
||||
- (int32_t) readTag {
|
||||
if (self.isAtEnd) {
|
||||
lastTag = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
lastTag = [self readRawVarint32];
|
||||
if (lastTag == 0) {
|
||||
// If we actually read zero, that's not a valid tag.
|
||||
@throw [NSException exceptionWithName:@"InvalidProtocolBuffer" reason:@"Invalid Tag" userInfo:nil];
|
||||
}
|
||||
return lastTag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that the last call to readTag() returned the given tag value.
|
||||
* This is used to verify that a nested group ended with the correct
|
||||
* end tag.
|
||||
*
|
||||
* @throws InvalidProtocolBufferException {@code value} does not match the
|
||||
* last tag.
|
||||
*/
|
||||
- (void) checkLastTagWas:(int32_t) value {
|
||||
if (lastTag != value) {
|
||||
@throw [NSException exceptionWithName:@"InvalidProtocolBuffer" reason:@"Invalid End Tag" userInfo:nil];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads and discards a single field, given its tag value.
|
||||
*
|
||||
* @return {@code NO} if the tag is an endgroup tag, in which case
|
||||
* nothing is skipped. Otherwise, returns {@code YES}.
|
||||
*/
|
||||
- (BOOL) skipField:(int32_t) tag {
|
||||
switch (PBWireFormatGetTagWireType(tag)) {
|
||||
case PBWireFormatVarint:
|
||||
[self readInt32];
|
||||
return YES;
|
||||
case PBWireFormatFixed64:
|
||||
[self readRawLittleEndian64];
|
||||
return YES;
|
||||
case PBWireFormatLengthDelimited:
|
||||
[self skipRawData:[self readRawVarint32]];
|
||||
return YES;
|
||||
case PBWireFormatStartGroup:
|
||||
[self skipMessage];
|
||||
[self checkLastTagWas:
|
||||
PBWireFormatMakeTag(PBWireFormatGetTagFieldNumber(tag),
|
||||
PBWireFormatEndGroup)];
|
||||
return YES;
|
||||
case PBWireFormatEndGroup:
|
||||
return NO;
|
||||
case PBWireFormatFixed32:
|
||||
[self readRawLittleEndian32];
|
||||
return YES;
|
||||
default:
|
||||
@throw [NSException exceptionWithName:@"InvalidProtocolBuffer" reason:@"Invalid Wire Type" userInfo:nil];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reads and discards an entire message. This will read either until EOF
|
||||
* or until an endgroup tag, whichever comes first.
|
||||
*/
|
||||
- (void) skipMessage {
|
||||
while (YES) {
|
||||
int32_t tag = [self readTag];
|
||||
if (tag == 0 || ![self skipField:tag]) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** Read a {@code double} field value from the stream. */
|
||||
- (Float64) readDouble {
|
||||
return convertInt64ToFloat64([self readRawLittleEndian64]);
|
||||
}
|
||||
|
||||
|
||||
/** Read a {@code float} field value from the stream. */
|
||||
- (Float32) readFloat {
|
||||
return convertInt32ToFloat32([self readRawLittleEndian32]);
|
||||
}
|
||||
|
||||
|
||||
/** Read a {@code uint64} field value from the stream. */
|
||||
- (int64_t) readUInt64 {
|
||||
return [self readRawVarint64];
|
||||
}
|
||||
|
||||
|
||||
/** Read an {@code int64} field value from the stream. */
|
||||
- (int64_t) readInt64 {
|
||||
return [self readRawVarint64];
|
||||
}
|
||||
|
||||
|
||||
/** Read an {@code int32} field value from the stream. */
|
||||
- (int32_t) readInt32 {
|
||||
return [self readRawVarint32];
|
||||
}
|
||||
|
||||
|
||||
/** Read a {@code fixed64} field value from the stream. */
|
||||
- (int64_t) readFixed64 {
|
||||
return [self readRawLittleEndian64];
|
||||
}
|
||||
|
||||
|
||||
/** Read a {@code fixed32} field value from the stream. */
|
||||
- (int32_t) readFixed32 {
|
||||
return [self readRawLittleEndian32];
|
||||
}
|
||||
|
||||
|
||||
/** Read a {@code bool} field value from the stream. */
|
||||
- (BOOL) readBool {
|
||||
return [self readRawVarint32] != 0;
|
||||
}
|
||||
|
||||
|
||||
/** Read a {@code string} field value from the stream. */
|
||||
- (NSString*) readString {
|
||||
int32_t size = [self readRawVarint32];
|
||||
if (size <= (bufferSize - bufferPos) && size > 0) {
|
||||
// Fast path: We already have the bytes in a contiguous buffer, so
|
||||
// just copy directly from it.
|
||||
// new String(buffer, bufferPos, size, "UTF-8");
|
||||
NSString* result = [[NSString alloc] initWithBytes:(((uint8_t*) buffer.bytes) + bufferPos)
|
||||
length:(NSUInteger)size
|
||||
encoding:NSUTF8StringEncoding];
|
||||
bufferPos += size;
|
||||
return result;
|
||||
} else {
|
||||
// Slow path: Build a byte array first then copy it.
|
||||
NSData* data = [self readRawData:size];
|
||||
return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** Read a {@code group} field value from the stream. */
|
||||
- (void) readGroup:(int32_t) fieldNumber
|
||||
builder:(id<PBMessage_Builder>) builder
|
||||
extensionRegistry:(PBExtensionRegistry*) extensionRegistry {
|
||||
if (recursionDepth >= recursionLimit) {
|
||||
@throw [NSException exceptionWithName:@"InvalidProtocolBuffer" reason:@"Recursion Limit Exceeded" userInfo:nil];
|
||||
}
|
||||
++recursionDepth;
|
||||
[builder mergeFromCodedInputStream:self extensionRegistry:extensionRegistry];
|
||||
[self checkLastTagWas:PBWireFormatMakeTag(fieldNumber, PBWireFormatEndGroup)];
|
||||
--recursionDepth;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reads a {@code group} field value from the stream and merges it into the
|
||||
* given {@link PBUnknownFieldSet}.
|
||||
*/
|
||||
- (void) readUnknownGroup:(int32_t) fieldNumber
|
||||
builder:(PBUnknownFieldSet_Builder*) builder {
|
||||
if (recursionDepth >= recursionLimit) {
|
||||
@throw [NSException exceptionWithName:@"InvalidProtocolBuffer" reason:@"Recursion Limit Exceeded" userInfo:nil];
|
||||
}
|
||||
++recursionDepth;
|
||||
[builder mergeFromCodedInputStream:self];
|
||||
[self checkLastTagWas:PBWireFormatMakeTag(fieldNumber, PBWireFormatEndGroup)];
|
||||
--recursionDepth;
|
||||
}
|
||||
|
||||
|
||||
/** Read an embedded message field value from the stream. */
|
||||
- (void) readMessage:(id<PBMessage_Builder>) builder
|
||||
extensionRegistry:(PBExtensionRegistry*) extensionRegistry {
|
||||
int32_t length = [self readRawVarint32];
|
||||
if (recursionDepth >= recursionLimit) {
|
||||
@throw [NSException exceptionWithName:@"InvalidProtocolBuffer" reason:@"Recursion Limit Exceeded" userInfo:nil];
|
||||
}
|
||||
int32_t oldLimit = [self pushLimit:length];
|
||||
++recursionDepth;
|
||||
[builder mergeFromCodedInputStream:self extensionRegistry:extensionRegistry];
|
||||
[self checkLastTagWas:0];
|
||||
--recursionDepth;
|
||||
[self popLimit:oldLimit];
|
||||
}
|
||||
|
||||
|
||||
/** Read a {@code bytes} field value from the stream. */
|
||||
- (NSData*) readData {
|
||||
int32_t size = [self readRawVarint32];
|
||||
if (size < bufferSize - bufferPos && size > 0) {
|
||||
// Fast path: We already have the bytes in a contiguous buffer, so
|
||||
// just copy directly from it.
|
||||
NSData* result = [NSData dataWithBytes:(((uint8_t*) buffer.bytes) + bufferPos) length:(NSUInteger)size];
|
||||
bufferPos += size;
|
||||
return result;
|
||||
} else {
|
||||
// Slow path: Build a byte array first then copy it.
|
||||
return [self readRawData:size];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** Read a {@code uint32} field value from the stream. */
|
||||
- (int32_t) readUInt32 {
|
||||
return [self readRawVarint32];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Read an enum field value from the stream. Caller is responsible
|
||||
* for converting the numeric value to an actual enum.
|
||||
*/
|
||||
- (int32_t) readEnum {
|
||||
return [self readRawVarint32];
|
||||
}
|
||||
|
||||
|
||||
/** Read an {@code sfixed32} field value from the stream. */
|
||||
- (int32_t) readSFixed32 {
|
||||
return [self readRawLittleEndian32];
|
||||
}
|
||||
|
||||
|
||||
/** Read an {@code sfixed64} field value from the stream. */
|
||||
- (int64_t) readSFixed64 {
|
||||
return [self readRawLittleEndian64];
|
||||
}
|
||||
|
||||
|
||||
/** Read an {@code sint32} field value from the stream. */
|
||||
- (int32_t) readSInt32 {
|
||||
return decodeZigZag32([self readRawVarint32]);
|
||||
}
|
||||
|
||||
|
||||
/** Read an {@code sint64} field value from the stream. */
|
||||
- (int64_t) readSInt64 {
|
||||
return decodeZigZag64([self readRawVarint64]);
|
||||
}
|
||||
|
||||
|
||||
// =================================================================
|
||||
|
||||
/**
|
||||
* Read a raw Varint from the stream. If larger than 32 bits, discard the
|
||||
* upper bits.
|
||||
*/
|
||||
- (int32_t) readRawVarint32 {
|
||||
int8_t tmp = [self readRawByte];
|
||||
if (tmp >= 0) {
|
||||
return tmp;
|
||||
}
|
||||
int32_t result = tmp & 0x7f;
|
||||
if ((tmp = [self readRawByte]) >= 0) {
|
||||
result |= tmp << 7;
|
||||
} else {
|
||||
result |= (tmp & 0x7f) << 7;
|
||||
if ((tmp = [self readRawByte]) >= 0) {
|
||||
result |= tmp << 14;
|
||||
} else {
|
||||
result |= (tmp & 0x7f) << 14;
|
||||
if ((tmp = [self readRawByte]) >= 0) {
|
||||
result |= tmp << 21;
|
||||
} else {
|
||||
result |= (tmp & 0x7f) << 21;
|
||||
result |= (tmp = [self readRawByte]) << 28;
|
||||
if (tmp < 0) {
|
||||
// Discard upper 32 bits.
|
||||
for (int i = 0; i < 5; i++) {
|
||||
if ([self readRawByte] >= 0) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@throw [NSException exceptionWithName:@"InvalidProtocolBuffer" reason:@"malformedVarint" userInfo:nil];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/** Read a raw Varint from the stream. */
|
||||
- (int64_t) readRawVarint64 {
|
||||
int32_t shift = 0;
|
||||
int64_t result = 0;
|
||||
while (shift < 64) {
|
||||
int8_t b = [self readRawByte];
|
||||
result |= (int64_t)(b & 0x7F) << shift;
|
||||
if ((b & 0x80) == 0) {
|
||||
return result;
|
||||
}
|
||||
shift += 7;
|
||||
}
|
||||
@throw [NSException exceptionWithName:@"InvalidProtocolBuffer" reason:@"malformedVarint" userInfo:nil];
|
||||
}
|
||||
|
||||
|
||||
/** Read a 32-bit little-endian integer from the stream. */
|
||||
- (int32_t) readRawLittleEndian32 {
|
||||
int8_t b1 = [self readRawByte];
|
||||
int8_t b2 = [self readRawByte];
|
||||
int8_t b3 = [self readRawByte];
|
||||
int8_t b4 = [self readRawByte];
|
||||
return
|
||||
(((int32_t)b1 & 0xff) ) |
|
||||
(((int32_t)b2 & 0xff) << 8) |
|
||||
(((int32_t)b3 & 0xff) << 16) |
|
||||
(((int32_t)b4 & 0xff) << 24);
|
||||
}
|
||||
|
||||
|
||||
/** Read a 64-bit little-endian integer from the stream. */
|
||||
- (int64_t) readRawLittleEndian64 {
|
||||
int8_t b1 = [self readRawByte];
|
||||
int8_t b2 = [self readRawByte];
|
||||
int8_t b3 = [self readRawByte];
|
||||
int8_t b4 = [self readRawByte];
|
||||
int8_t b5 = [self readRawByte];
|
||||
int8_t b6 = [self readRawByte];
|
||||
int8_t b7 = [self readRawByte];
|
||||
int8_t b8 = [self readRawByte];
|
||||
return
|
||||
(((int64_t)b1 & 0xff) ) |
|
||||
(((int64_t)b2 & 0xff) << 8) |
|
||||
(((int64_t)b3 & 0xff) << 16) |
|
||||
(((int64_t)b4 & 0xff) << 24) |
|
||||
(((int64_t)b5 & 0xff) << 32) |
|
||||
(((int64_t)b6 & 0xff) << 40) |
|
||||
(((int64_t)b7 & 0xff) << 48) |
|
||||
(((int64_t)b8 & 0xff) << 56);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Decode a ZigZag-encoded 32-bit value. ZigZag encodes signed integers
|
||||
* into values that can be efficiently encoded with varint. (Otherwise,
|
||||
* negative values must be sign-extended to 64 bits to be varint encoded,
|
||||
* thus always taking 10 bytes on the wire.)
|
||||
*
|
||||
* @param n An unsigned 32-bit integer, stored in a signed int
|
||||
* @return A signed 32-bit integer.
|
||||
*/
|
||||
int32_t decodeZigZag32(int32_t n) {
|
||||
return logicalRightShift32(n, 1) ^ -(n & 1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Decode a ZigZag-encoded 64-bit value. ZigZag encodes signed integers
|
||||
* into values that can be efficiently encoded with varint. (Otherwise,
|
||||
* negative values must be sign-extended to 64 bits to be varint encoded,
|
||||
* thus always taking 10 bytes on the wire.)
|
||||
*
|
||||
* @param n An unsigned 64-bit integer, stored in a signed int
|
||||
* @return A signed 64-bit integer.
|
||||
*/
|
||||
int64_t decodeZigZag64(int64_t n) {
|
||||
return logicalRightShift64(n, 1) ^ -(n & 1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the maximum message recursion depth. In order to prevent malicious
|
||||
* messages from causing stack overflows, {@code PBCodedInputStream} limits
|
||||
* how deeply messages may be nested. The default limit is 64.
|
||||
*
|
||||
* @return the old limit.
|
||||
*/
|
||||
- (int32_t) setRecursionLimit:(int32_t) limit {
|
||||
if (limit < 0) {
|
||||
@throw [NSException exceptionWithName:@"IllegalArgument" reason:@"Recursion limit cannot be negative" userInfo:nil];
|
||||
}
|
||||
int32_t oldLimit = recursionLimit;
|
||||
recursionLimit = limit;
|
||||
return oldLimit;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the maximum message size. In order to prevent malicious
|
||||
* messages from exhausting memory or causing integer overflows,
|
||||
* {@code PBCodedInputStream} limits how large a message may be.
|
||||
* The default limit is 64MB. You should set this limit as small
|
||||
* as you can without harming your app's functionality. Note that
|
||||
* size limits only apply when reading from an {@code InputStream}, not
|
||||
* when constructed around a raw byte array.
|
||||
*
|
||||
* @return the old limit.
|
||||
*/
|
||||
- (int32_t) setSizeLimit:(int32_t) limit {
|
||||
if (limit < 0) {
|
||||
@throw [NSException exceptionWithName:@"IllegalArgument" reason:@"Size limit cannot be negative:" userInfo:nil];
|
||||
}
|
||||
int32_t oldLimit = sizeLimit;
|
||||
sizeLimit = limit;
|
||||
return oldLimit;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Resets the current size counter to zero (see {@link #setSizeLimit(int)}).
|
||||
*/
|
||||
- (void) resetSizeCounter {
|
||||
totalBytesRetired = 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets {@code currentLimit} to (current position) + {@code byteLimit}. This
|
||||
* is called when descending into a length-delimited embedded message.
|
||||
*
|
||||
* @return the old limit.
|
||||
*/
|
||||
- (int32_t) pushLimit:(int32_t) byteLimit {
|
||||
if (byteLimit < 0) {
|
||||
@throw [NSException exceptionWithName:@"InvalidProtocolBuffer" reason:@"negativeSize" userInfo:nil];
|
||||
}
|
||||
byteLimit += totalBytesRetired + bufferPos;
|
||||
int32_t oldLimit = currentLimit;
|
||||
if (byteLimit > oldLimit) {
|
||||
@throw [NSException exceptionWithName:@"InvalidProtocolBuffer" reason:@"truncatedMessage" userInfo:nil];
|
||||
}
|
||||
currentLimit = byteLimit;
|
||||
|
||||
[self recomputeBufferSizeAfterLimit];
|
||||
|
||||
return oldLimit;
|
||||
}
|
||||
|
||||
|
||||
- (void) recomputeBufferSizeAfterLimit {
|
||||
bufferSize += bufferSizeAfterLimit;
|
||||
int32_t bufferEnd = totalBytesRetired + bufferSize;
|
||||
if (bufferEnd > currentLimit) {
|
||||
// Limit is in current buffer.
|
||||
bufferSizeAfterLimit = bufferEnd - currentLimit;
|
||||
bufferSize -= bufferSizeAfterLimit;
|
||||
} else {
|
||||
bufferSizeAfterLimit = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Discards the current limit, returning to the previous limit.
|
||||
*
|
||||
* @param oldLimit The old limit, as returned by {@code pushLimit}.
|
||||
*/
|
||||
- (void) popLimit:(int32_t) oldLimit {
|
||||
currentLimit = oldLimit;
|
||||
[self recomputeBufferSizeAfterLimit];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the number of bytes to be read before the current limit.
|
||||
* If no limit is set, returns -1.
|
||||
*/
|
||||
- (int32_t) bytesUntilLimit {
|
||||
if (currentLimit == INT_MAX) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int32_t currentAbsolutePosition = totalBytesRetired + bufferPos;
|
||||
return currentLimit - currentAbsolutePosition;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the stream has reached the end of the input. This is the
|
||||
* case if either the end of the underlying input source has been reached or
|
||||
* if the stream has reached a limit created using {@link #pushLimit(int)}.
|
||||
*/
|
||||
- (BOOL) isAtEnd {
|
||||
return bufferPos == bufferSize && ![self refillBuffer:NO];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Called with {@code this.buffer} is empty to read more bytes from the
|
||||
* input. If {@code mustSucceed} is YES, refillBuffer() gurantees that
|
||||
* either there will be at least one byte in the buffer when it returns
|
||||
* or it will throw an exception. If {@code mustSucceed} is NO,
|
||||
* refillBuffer() returns NO if no more bytes were available.
|
||||
*/
|
||||
- (BOOL) refillBuffer:(BOOL) mustSucceed {
|
||||
if (bufferPos < bufferSize) {
|
||||
@throw [NSException exceptionWithName:@"IllegalState" reason:@"refillBuffer called when buffer wasn't empty." userInfo:nil];
|
||||
}
|
||||
|
||||
if (totalBytesRetired + bufferSize == currentLimit) {
|
||||
// Oops, we hit a limit.
|
||||
if (mustSucceed) {
|
||||
@throw [NSException exceptionWithName:@"InvalidProtocolBuffer" reason:@"truncatedMessage" userInfo:nil];
|
||||
} else {
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
||||
totalBytesRetired += bufferSize;
|
||||
|
||||
// TODO(cyrusn): does NSInputStream behave the same as java.io.InputStream
|
||||
// when there is no more data?
|
||||
bufferPos = 0;
|
||||
bufferSize = 0;
|
||||
if (input != nil) {
|
||||
bufferSize = (int32_t)[input read:buffer.mutableBytes maxLength:buffer.length];
|
||||
}
|
||||
|
||||
if (bufferSize <= 0) {
|
||||
bufferSize = 0;
|
||||
if (mustSucceed) {
|
||||
@throw [NSException exceptionWithName:@"InvalidProtocolBuffer" reason:@"truncatedMessage" userInfo:nil];
|
||||
} else {
|
||||
return NO;
|
||||
}
|
||||
} else {
|
||||
[self recomputeBufferSizeAfterLimit];
|
||||
NSInteger totalBytesRead = totalBytesRetired + bufferSize + bufferSizeAfterLimit;
|
||||
if (totalBytesRead > sizeLimit || totalBytesRead < 0) {
|
||||
@throw [NSException exceptionWithName:@"InvalidProtocolBuffer" reason:@"sizeLimitExceeded" userInfo:nil];
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Read one byte from the input.
|
||||
*
|
||||
* @throws InvalidProtocolBufferException The end of the stream or the current
|
||||
* limit was reached.
|
||||
*/
|
||||
- (int8_t) readRawByte {
|
||||
if (bufferPos == bufferSize) {
|
||||
[self refillBuffer:YES];
|
||||
}
|
||||
int8_t* bytes = (int8_t*)buffer.bytes;
|
||||
return bytes[bufferPos++];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Read a fixed size of bytes from the input.
|
||||
*
|
||||
* @throws InvalidProtocolBufferException The end of the stream or the current
|
||||
* limit was reached.
|
||||
*/
|
||||
- (NSData*) readRawData:(int32_t) size {
|
||||
if (size < 0) {
|
||||
@throw [NSException exceptionWithName:@"InvalidProtocolBuffer" reason:@"negativeSize" userInfo:nil];
|
||||
}
|
||||
|
||||
if (totalBytesRetired + bufferPos + size > currentLimit) {
|
||||
// Read to the end of the stream anyway.
|
||||
[self skipRawData:currentLimit - totalBytesRetired - bufferPos];
|
||||
// Then fail.
|
||||
@throw [NSException exceptionWithName:@"InvalidProtocolBuffer" reason:@"truncatedMessage" userInfo:nil];
|
||||
}
|
||||
|
||||
if (size <= bufferSize - bufferPos) {
|
||||
// We have all the bytes we need already.
|
||||
NSData* data = [NSData dataWithBytes:(((int8_t*) buffer.bytes) + bufferPos) length:(NSUInteger)size];
|
||||
bufferPos += size;
|
||||
return data;
|
||||
} else if (size < BUFFER_SIZE) {
|
||||
// Reading more bytes than are in the buffer, but not an excessive number
|
||||
// of bytes. We can safely allocate the resulting array ahead of time.
|
||||
|
||||
// First copy what we have.
|
||||
NSMutableData* bytes = [NSMutableData dataWithLength:(NSUInteger)size];
|
||||
int32_t pos = bufferSize - bufferPos;
|
||||
memcpy(bytes.mutableBytes, ((int8_t*)buffer.bytes) + bufferPos, pos);
|
||||
bufferPos = bufferSize;
|
||||
|
||||
// We want to use refillBuffer() and then copy from the buffer into our
|
||||
// byte array rather than reading directly into our byte array because
|
||||
// the input may be unbuffered.
|
||||
[self refillBuffer:YES];
|
||||
|
||||
while (size - pos > bufferSize) {
|
||||
memcpy(((int8_t*)bytes.mutableBytes) + pos, buffer.bytes, bufferSize);
|
||||
pos += bufferSize;
|
||||
bufferPos = bufferSize;
|
||||
[self refillBuffer:YES];
|
||||
}
|
||||
|
||||
memcpy(((int8_t*)bytes.mutableBytes) + pos, buffer.bytes, size - pos);
|
||||
bufferPos = size - pos;
|
||||
|
||||
return bytes;
|
||||
} else {
|
||||
// The size is very large. For security reasons, we can't allocate the
|
||||
// entire byte array yet. The size comes directly from the input, so a
|
||||
// maliciously-crafted message could provide a bogus very large size in
|
||||
// order to trick the app into allocating a lot of memory. We avoid this
|
||||
// by allocating and reading only a small chunk at a time, so that the
|
||||
// malicious message must actuall* e* extremely large to cause
|
||||
// problems. Meanwhile, we limit the allowed size of a message elsewhere.
|
||||
|
||||
// Remember the buffer markers since we'll have to copy the bytes out of
|
||||
// it later.
|
||||
int32_t originalBufferPos = bufferPos;
|
||||
int32_t originalBufferSize = bufferSize;
|
||||
|
||||
// Mark the current buffer consumed.
|
||||
totalBytesRetired += bufferSize;
|
||||
bufferPos = 0;
|
||||
bufferSize = 0;
|
||||
|
||||
// Read all the rest of the bytes we need.
|
||||
int32_t sizeLeft = size - (originalBufferSize - originalBufferPos);
|
||||
NSMutableArray* chunks = [NSMutableArray array];
|
||||
|
||||
while (sizeLeft > 0) {
|
||||
NSMutableData* chunk = [NSMutableData dataWithLength:(NSUInteger)MIN(sizeLeft, BUFFER_SIZE)];
|
||||
|
||||
int32_t pos = 0;
|
||||
while (pos < (int32_t)chunk.length) {
|
||||
int32_t n = 0;
|
||||
if (input != nil) {
|
||||
n = (int32_t)[input read:(((uint8_t*) chunk.mutableBytes) + pos) maxLength:chunk.length - (NSUInteger)pos];
|
||||
}
|
||||
if (n <= 0) {
|
||||
@throw [NSException exceptionWithName:@"InvalidProtocolBuffer" reason:@"truncatedMessage" userInfo:nil];
|
||||
}
|
||||
totalBytesRetired += n;
|
||||
pos += n;
|
||||
}
|
||||
sizeLeft -= chunk.length;
|
||||
[chunks addObject:chunk];
|
||||
}
|
||||
|
||||
// OK, got everything. Now concatenate it all into one buffer.
|
||||
NSMutableData* bytes = [NSMutableData dataWithLength:(NSUInteger)size];
|
||||
|
||||
// Start by copying the leftover bytes from this.buffer.
|
||||
int32_t pos = originalBufferSize - originalBufferPos;
|
||||
memcpy(bytes.mutableBytes, ((int8_t*)buffer.bytes) + originalBufferPos, pos);
|
||||
|
||||
// And now all the chunks.
|
||||
for (NSData* chunk in chunks) {
|
||||
memcpy(((int8_t*)bytes.mutableBytes) + pos, chunk.bytes, chunk.length);
|
||||
pos += chunk.length;
|
||||
}
|
||||
|
||||
// Done.
|
||||
return bytes;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reads and discards {@code size} bytes.
|
||||
*
|
||||
* @throws InvalidProtocolBufferException The end of the stream or the current
|
||||
* limit was reached.
|
||||
*/
|
||||
- (void) skipRawData:(int32_t) size {
|
||||
if (size < 0) {
|
||||
@throw [NSException exceptionWithName:@"InvalidProtocolBuffer" reason:@"negativeSize" userInfo:nil];
|
||||
}
|
||||
|
||||
if (totalBytesRetired + bufferPos + size > currentLimit) {
|
||||
// Read to the end of the stream anyway.
|
||||
[self skipRawData:currentLimit - totalBytesRetired - bufferPos];
|
||||
// Then fail.
|
||||
@throw [NSException exceptionWithName:@"InvalidProtocolBuffer" reason:@"truncatedMessage" userInfo:nil];
|
||||
}
|
||||
|
||||
if (size <= (bufferSize - bufferPos)) {
|
||||
// We have all the bytes we need already.
|
||||
bufferPos += size;
|
||||
} else {
|
||||
// Skipping more bytes than are in the buffer. First skip what we have.
|
||||
int32_t pos = bufferSize - bufferPos;
|
||||
totalBytesRetired += pos;
|
||||
bufferPos = 0;
|
||||
bufferSize = 0;
|
||||
|
||||
// Then skip directly from the InputStream for the rest.
|
||||
while (pos < size) {
|
||||
NSMutableData* data = [NSMutableData dataWithLength:(NSUInteger)(size - pos)];
|
||||
int32_t n = (input == nil) ? -1 : (int32_t)[input read:data.mutableBytes maxLength:(NSUInteger)(size - pos)];
|
||||
if (n <= 0) {
|
||||
@throw [NSException exceptionWithName:@"InvalidProtocolBuffer" reason:@"truncatedMessage" userInfo:nil];
|
||||
}
|
||||
pos += n;
|
||||
totalBytesRetired += n;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@end
|
|
@ -1,216 +0,0 @@
|
|||
// 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.
|
||||
|
||||
@class PBUnknownFieldSet;
|
||||
@protocol PBMessage;
|
||||
|
||||
/**
|
||||
* Encodes and writes protocol message fields.
|
||||
*
|
||||
* <p>This class contains two kinds of methods: methods that write specific
|
||||
* protocol message constructs and field types (e.g. {@link #writeTag} and
|
||||
* {@link #writeInt32}) and methods that write low-level values (e.g.
|
||||
* {@link #writeRawVarint32} and {@link #writeRawBytes}). If you are
|
||||
* writing encoded protocol messages, you should use the former methods, but if
|
||||
* you are writing some other format of your own design, use the latter.
|
||||
*
|
||||
* <p>This class is totally unsynchronized.
|
||||
*
|
||||
* @author Cyrus Najmabadi
|
||||
*/
|
||||
@interface PBCodedOutputStream : NSObject {
|
||||
NSMutableData* buffer;
|
||||
int32_t position;
|
||||
NSOutputStream* output;
|
||||
}
|
||||
|
||||
+ (PBCodedOutputStream*) streamWithData:(NSMutableData*) data;
|
||||
+ (PBCodedOutputStream*) streamWithOutputStream:(NSOutputStream*) output;
|
||||
+ (PBCodedOutputStream*) streamWithOutputStream:(NSOutputStream*) output bufferSize:(int32_t) bufferSize;
|
||||
|
||||
|
||||
/**
|
||||
* Encode a ZigZag-encoded 32-bit value. ZigZag encodes signed integers
|
||||
* into values that can be efficiently encoded with varint. (Otherwise,
|
||||
* negative values must be sign-extended to 64 bits to be varint encoded,
|
||||
* thus always taking 10 bytes on the wire.)
|
||||
*
|
||||
* @param n A signed 32-bit integer.
|
||||
* @return An unsigned 32-bit integer, stored in a signed int.
|
||||
*/
|
||||
int32_t encodeZigZag32(int32_t n);
|
||||
|
||||
/**
|
||||
* Encode a ZigZag-encoded 64-bit value. ZigZag encodes signed integers
|
||||
* into values that can be efficiently encoded with varint. (Otherwise,
|
||||
* negative values must be sign-extended to 64 bits to be varint encoded,
|
||||
* thus always taking 10 bytes on the wire.)
|
||||
*
|
||||
* @param n A signed 64-bit integer.
|
||||
* @return An unsigned 64-bit integer, stored in a signed int.
|
||||
*/
|
||||
int64_t encodeZigZag64(int64_t n);
|
||||
|
||||
int32_t computeDoubleSize(int32_t fieldNumber, Float64 value);
|
||||
int32_t computeFloatSize(int32_t fieldNumber, Float32 value);
|
||||
int32_t computeUInt64Size(int32_t fieldNumber, int64_t value);
|
||||
int32_t computeInt64Size(int32_t fieldNumber, int64_t value);
|
||||
int32_t computeInt32Size(int32_t fieldNumber, int32_t value);
|
||||
int32_t computeFixed64Size(int32_t fieldNumber, int64_t value);
|
||||
int32_t computeFixed32Size(int32_t fieldNumber, int32_t value);
|
||||
int32_t computeBoolSize(int32_t fieldNumber, BOOL value);
|
||||
int32_t computeStringSize(int32_t fieldNumber, NSString* value);
|
||||
int32_t computeGroupSize(int32_t fieldNumber, id<PBMessage> value);
|
||||
int32_t computeUnknownGroupSize(int32_t fieldNumber, PBUnknownFieldSet* value);
|
||||
int32_t computeMessageSize(int32_t fieldNumber, id<PBMessage> value);
|
||||
int32_t computeDataSize(int32_t fieldNumber, NSData* value);
|
||||
int32_t computeUInt32Size(int32_t fieldNumber, int32_t value);
|
||||
int32_t computeSFixed32Size(int32_t fieldNumber, int32_t value);
|
||||
int32_t computeSFixed64Size(int32_t fieldNumber, int64_t value);
|
||||
int32_t computeSInt32Size(int32_t fieldNumber, int32_t value);
|
||||
int32_t computeSInt64Size(int32_t fieldNumber, int64_t value);
|
||||
int32_t computeTagSize(int32_t fieldNumber);
|
||||
|
||||
int32_t computeDoubleSizeNoTag(Float64 value);
|
||||
int32_t computeFloatSizeNoTag(Float32 value);
|
||||
int32_t computeUInt64SizeNoTag(int64_t value);
|
||||
int32_t computeInt64SizeNoTag(int64_t value);
|
||||
int32_t computeInt32SizeNoTag(int32_t value);
|
||||
int32_t computeFixed64SizeNoTag(int64_t value);
|
||||
int32_t computeFixed32SizeNoTag(int32_t value);
|
||||
int32_t computeBoolSizeNoTag(BOOL value);
|
||||
int32_t computeStringSizeNoTag(NSString* value);
|
||||
int32_t computeGroupSizeNoTag(id<PBMessage> value);
|
||||
int32_t computeUnknownGroupSizeNoTag(PBUnknownFieldSet* value);
|
||||
int32_t computeMessageSizeNoTag(id<PBMessage> value);
|
||||
int32_t computeDataSizeNoTag(NSData* value);
|
||||
int32_t computeUInt32SizeNoTag(int32_t value);
|
||||
int32_t computeEnumSizeNoTag(int32_t value);
|
||||
int32_t computeSFixed32SizeNoTag(int32_t value);
|
||||
int32_t computeSFixed64SizeNoTag(int64_t value);
|
||||
int32_t computeSInt32SizeNoTag(int32_t value);
|
||||
int32_t computeSInt64SizeNoTag(int64_t value);
|
||||
|
||||
/**
|
||||
* Compute the number of bytes that would be needed to encode a varint.
|
||||
* {@code value} is treated as unsigned, so it won't be sign-extended if
|
||||
* negative.
|
||||
*/
|
||||
int32_t computeRawVarint32Size(int32_t value);
|
||||
int32_t computeRawVarint64Size(int64_t value);
|
||||
|
||||
/**
|
||||
* Compute the number of bytes that would be needed to encode a
|
||||
* MessageSet extension to the stream. For historical reasons,
|
||||
* the wire format differs from normal fields.
|
||||
*/
|
||||
int32_t computeMessageSetExtensionSize(int32_t fieldNumber, id<PBMessage> value);
|
||||
|
||||
/**
|
||||
* Compute the number of bytes that would be needed to encode an
|
||||
* unparsed MessageSet extension field to the stream. For
|
||||
* historical reasons, the wire format differs from normal fields.
|
||||
*/
|
||||
int32_t computeRawMessageSetExtensionSize(int32_t fieldNumber, NSData* value);
|
||||
|
||||
/**
|
||||
* Compute the number of bytes that would be needed to encode an
|
||||
* enum field, including tag. Caller is responsible for converting the
|
||||
* enum value to its numeric value.
|
||||
*/
|
||||
int32_t computeEnumSize(int32_t fieldNumber, int32_t value);
|
||||
|
||||
/**
|
||||
* Flushes the stream and forces any buffered bytes to be written. This
|
||||
* does not flush the underlying NSOutputStream.
|
||||
*/
|
||||
- (void) flush;
|
||||
|
||||
- (void) writeRawByte:(uint8_t) value;
|
||||
|
||||
- (void) writeTag:(int32_t) fieldNumber format:(int32_t) format;
|
||||
|
||||
/**
|
||||
* Encode and write a varint. {@code value} is treated as
|
||||
* unsigned, so it won't be sign-extended if negative.
|
||||
*/
|
||||
- (void) writeRawVarint32:(int32_t) value;
|
||||
- (void) writeRawVarint64:(int64_t) value;
|
||||
|
||||
- (void) writeRawLittleEndian32:(int32_t) value;
|
||||
- (void) writeRawLittleEndian64:(int64_t) value;
|
||||
|
||||
- (void) writeRawData:(NSData*) data;
|
||||
- (void) writeRawData:(NSData*) data offset:(int32_t) offset length:(int32_t) length;
|
||||
|
||||
- (void) writeData:(int32_t) fieldNumber value:(NSData*) value;
|
||||
|
||||
- (void) writeDouble:(int32_t) fieldNumber value:(Float64) value;
|
||||
- (void) writeFloat:(int32_t) fieldNumber value:(Float32) value;
|
||||
- (void) writeUInt64:(int32_t) fieldNumber value:(int64_t) value;
|
||||
- (void) writeInt64:(int32_t) fieldNumber value:(int64_t) value;
|
||||
- (void) writeInt32:(int32_t) fieldNumber value:(int32_t) value;
|
||||
- (void) writeFixed64:(int32_t) fieldNumber value:(int64_t) value;
|
||||
- (void) writeFixed32:(int32_t) fieldNumber value:(int32_t) value;
|
||||
- (void) writeBool:(int32_t) fieldNumber value:(BOOL) value;
|
||||
- (void) writeString:(int32_t) fieldNumber value:(NSString*) value;
|
||||
- (void) writeGroup:(int32_t) fieldNumber value:(id<PBMessage>) value;
|
||||
- (void) writeUnknownGroup:(int32_t) fieldNumber value:(PBUnknownFieldSet*) value;
|
||||
- (void) writeMessage:(int32_t) fieldNumber value:(id<PBMessage>) value;
|
||||
- (void) writeUInt32:(int32_t) fieldNumber value:(int32_t) value;
|
||||
- (void) writeSFixed32:(int32_t) fieldNumber value:(int32_t) value;
|
||||
- (void) writeSFixed64:(int32_t) fieldNumber value:(int64_t) value;
|
||||
- (void) writeSInt32:(int32_t) fieldNumber value:(int32_t) value;
|
||||
- (void) writeSInt64:(int32_t) fieldNumber value:(int64_t) value;
|
||||
|
||||
- (void) writeDoubleNoTag:(Float64) value;
|
||||
- (void) writeFloatNoTag:(Float32) value;
|
||||
- (void) writeUInt64NoTag:(int64_t) value;
|
||||
- (void) writeInt64NoTag:(int64_t) value;
|
||||
- (void) writeInt32NoTag:(int32_t) value;
|
||||
- (void) writeFixed64NoTag:(int64_t) value;
|
||||
- (void) writeFixed32NoTag:(int32_t) value;
|
||||
- (void) writeBoolNoTag:(BOOL) value;
|
||||
- (void) writeStringNoTag:(NSString*) value;
|
||||
- (void) writeGroupNoTag:(int32_t) fieldNumber value:(id<PBMessage>) value;
|
||||
- (void) writeUnknownGroupNoTag:(int32_t) fieldNumber value:(PBUnknownFieldSet*) value;
|
||||
- (void) writeMessageNoTag:(id<PBMessage>) value;
|
||||
- (void) writeDataNoTag:(NSData*) value;
|
||||
- (void) writeUInt32NoTag:(int32_t) value;
|
||||
- (void) writeEnumNoTag:(int32_t) value;
|
||||
- (void) writeSFixed32NoTag:(int32_t) value;
|
||||
- (void) writeSFixed64NoTag:(int64_t) value;
|
||||
- (void) writeSInt32NoTag:(int32_t) value;
|
||||
- (void) writeSInt64NoTag:(int64_t) value;
|
||||
|
||||
|
||||
/**
|
||||
* Write a MessageSet extension field to the stream. For historical reasons,
|
||||
* the wire format differs from normal fields.
|
||||
*/
|
||||
- (void) writeMessageSetExtension:(int32_t) fieldNumber value:(id<PBMessage>) value;
|
||||
|
||||
/**
|
||||
* Write an unparsed MessageSet extension field to the stream. For
|
||||
* historical reasons, the wire format differs from normal fields.
|
||||
*/
|
||||
- (void) writeRawMessageSetExtension:(int32_t) fieldNumber value:(NSData*) value;
|
||||
|
||||
/**
|
||||
* Write an enum field, including tag, to the stream. Caller is responsible
|
||||
* for converting the enum value to its numeric value.
|
||||
*/
|
||||
- (void) writeEnum:(int32_t) fieldNumber value:(int32_t) value;
|
||||
|
||||
@end
|
|
@ -1,974 +0,0 @@
|
|||
// 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 "CodedOutputStream.h"
|
||||
|
||||
#import "Message.h"
|
||||
#import "Utilities.h"
|
||||
#import "WireFormat.h"
|
||||
#import "UnknownFieldSet.h"
|
||||
|
||||
@interface PBCodedOutputStream ()
|
||||
@property (retain) NSMutableData* buffer;
|
||||
@property int32_t position;
|
||||
@property (retain) NSOutputStream* output;
|
||||
@end
|
||||
|
||||
|
||||
@implementation PBCodedOutputStream
|
||||
|
||||
const int32_t DEFAULT_BUFFER_SIZE = 4096;
|
||||
const int32_t LITTLE_ENDIAN_32_SIZE = 4;
|
||||
const int32_t LITTLE_ENDIAN_64_SIZE = 8;
|
||||
|
||||
@synthesize output;
|
||||
@synthesize buffer;
|
||||
@synthesize position;
|
||||
|
||||
- (void) dealloc {
|
||||
[output close];
|
||||
self.output = nil;
|
||||
self.buffer = nil;
|
||||
self.position = 0;
|
||||
}
|
||||
|
||||
|
||||
- (id) initWithOutputStream:(NSOutputStream*) output_
|
||||
data:(NSMutableData*) data_ {
|
||||
if ((self = [super init])) {
|
||||
self.output = output_;
|
||||
self.buffer = data_;
|
||||
self.position = 0;
|
||||
|
||||
[output open];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
+ (PBCodedOutputStream*) streamWithOutputStream:(NSOutputStream*) output
|
||||
bufferSize:(int32_t) bufferSize {
|
||||
NSMutableData* data = [NSMutableData dataWithLength:(NSUInteger)bufferSize];
|
||||
return [[PBCodedOutputStream alloc] initWithOutputStream:output
|
||||
data:data];
|
||||
}
|
||||
|
||||
|
||||
+ (PBCodedOutputStream*) streamWithOutputStream:(NSOutputStream*) output {
|
||||
return [PBCodedOutputStream streamWithOutputStream:output bufferSize:DEFAULT_BUFFER_SIZE];
|
||||
}
|
||||
|
||||
|
||||
+ (PBCodedOutputStream*) streamWithData:(NSMutableData*) data {
|
||||
return [[PBCodedOutputStream alloc] initWithOutputStream:nil data:data];
|
||||
}
|
||||
|
||||
|
||||
- (void) writeDoubleNoTag:(Float64) value {
|
||||
[self writeRawLittleEndian64:convertFloat64ToInt64(value)];
|
||||
}
|
||||
|
||||
|
||||
/** Write a {@code double} field, including tag, to the stream. */
|
||||
- (void) writeDouble:(int32_t) fieldNumber
|
||||
value:(Float64) value {
|
||||
[self writeTag:fieldNumber format:PBWireFormatFixed64];
|
||||
[self writeDoubleNoTag:value];
|
||||
}
|
||||
|
||||
|
||||
- (void) writeFloatNoTag:(Float32) value {
|
||||
[self writeRawLittleEndian32:convertFloat32ToInt32(value)];
|
||||
}
|
||||
|
||||
|
||||
/** Write a {@code float} field, including tag, to the stream. */
|
||||
- (void) writeFloat:(int32_t) fieldNumber
|
||||
value:(Float32) value {
|
||||
[self writeTag:fieldNumber format:PBWireFormatFixed32];
|
||||
[self writeFloatNoTag:value];
|
||||
}
|
||||
|
||||
|
||||
- (void) writeUInt64NoTag:(int64_t) value {
|
||||
[self writeRawVarint64:value];
|
||||
}
|
||||
|
||||
|
||||
/** Write a {@code uint64} field, including tag, to the stream. */
|
||||
- (void) writeUInt64:(int32_t) fieldNumber
|
||||
value:(int64_t) value {
|
||||
[self writeTag:fieldNumber format:PBWireFormatVarint];
|
||||
[self writeUInt64NoTag:value];
|
||||
}
|
||||
|
||||
|
||||
- (void) writeInt64NoTag:(int64_t) value {
|
||||
[self writeRawVarint64:value];
|
||||
}
|
||||
|
||||
|
||||
/** Write an {@code int64} field, including tag, to the stream. */
|
||||
- (void) writeInt64:(int32_t) fieldNumber
|
||||
value:(int64_t) value {
|
||||
[self writeTag:fieldNumber format:PBWireFormatVarint];
|
||||
[self writeInt64NoTag:value];
|
||||
}
|
||||
|
||||
|
||||
- (void) writeInt32NoTag:(int32_t) value {
|
||||
if (value >= 0) {
|
||||
[self writeRawVarint32:value];
|
||||
} else {
|
||||
// Must sign-extend
|
||||
[self writeRawVarint64:value];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** Write an {@code int32} field, including tag, to the stream. */
|
||||
- (void) writeInt32:(int32_t) fieldNumber
|
||||
value:(int32_t) value {
|
||||
[self writeTag:fieldNumber format:PBWireFormatVarint];
|
||||
[self writeInt32NoTag:value];
|
||||
}
|
||||
|
||||
|
||||
- (void) writeFixed64NoTag:(int64_t) value {
|
||||
[self writeRawLittleEndian64:value];
|
||||
}
|
||||
|
||||
|
||||
/** Write a {@code fixed64} field, including tag, to the stream. */
|
||||
- (void) writeFixed64:(int32_t) fieldNumber
|
||||
value:(int64_t) value {
|
||||
[self writeTag:fieldNumber format:PBWireFormatFixed64];
|
||||
[self writeFixed64NoTag:value];
|
||||
}
|
||||
|
||||
|
||||
- (void) writeFixed32NoTag:(int32_t) value {
|
||||
[self writeRawLittleEndian32:value];
|
||||
}
|
||||
|
||||
|
||||
/** Write a {@code fixed32} field, including tag, to the stream. */
|
||||
- (void) writeFixed32:(int32_t) fieldNumber
|
||||
value:(int32_t) value {
|
||||
[self writeTag:fieldNumber format:PBWireFormatFixed32];
|
||||
[self writeFixed32NoTag:value];
|
||||
}
|
||||
|
||||
|
||||
- (void) writeBoolNoTag:(BOOL) value {
|
||||
[self writeRawByte:(value ? 1 : 0)];
|
||||
}
|
||||
|
||||
|
||||
/** Write a {@code bool} field, including tag, to the stream. */
|
||||
- (void) writeBool:(int32_t) fieldNumber
|
||||
value:(BOOL) value {
|
||||
[self writeTag:fieldNumber format:PBWireFormatVarint];
|
||||
[self writeBoolNoTag:value];
|
||||
}
|
||||
|
||||
|
||||
- (void) writeStringNoTag:(NSString*) value {
|
||||
NSData* data = [value dataUsingEncoding:NSUTF8StringEncoding];
|
||||
[self writeRawVarint32:(int32_t)data.length];
|
||||
[self writeRawData:data];
|
||||
}
|
||||
|
||||
|
||||
/** Write a {@code string} field, including tag, to the stream. */
|
||||
- (void) writeString:(int32_t) fieldNumber
|
||||
value:(NSString*) value {
|
||||
// TODO(cyrusn): we could probably use:
|
||||
// NSString:getBytes:maxLength:usedLength:encoding:options:range:remainingRange:
|
||||
// to write directly into our buffer.
|
||||
[self writeTag:fieldNumber format:PBWireFormatLengthDelimited];
|
||||
[self writeStringNoTag:value];
|
||||
}
|
||||
|
||||
|
||||
- (void) writeGroupNoTag:(int32_t) fieldNumber
|
||||
value:(id<PBMessage>) value {
|
||||
[value writeToCodedOutputStream:self];
|
||||
[self writeTag:fieldNumber format:PBWireFormatEndGroup];
|
||||
}
|
||||
|
||||
|
||||
/** Write a {@code group} field, including tag, to the stream. */
|
||||
- (void) writeGroup:(int32_t) fieldNumber
|
||||
value:(id<PBMessage>) value {
|
||||
[self writeTag:fieldNumber format:PBWireFormatStartGroup];
|
||||
[self writeGroupNoTag:fieldNumber value:value];
|
||||
}
|
||||
|
||||
|
||||
- (void) writeUnknownGroupNoTag:(int32_t) fieldNumber
|
||||
value:(PBUnknownFieldSet*) value {
|
||||
[value writeToCodedOutputStream:self];
|
||||
[self writeTag:fieldNumber format:PBWireFormatEndGroup];
|
||||
}
|
||||
|
||||
|
||||
/** Write a group represented by an {@link PBUnknownFieldSet}. */
|
||||
- (void) writeUnknownGroup:(int32_t) fieldNumber
|
||||
value:(PBUnknownFieldSet*) value {
|
||||
[self writeTag:fieldNumber format:PBWireFormatStartGroup];
|
||||
[self writeUnknownGroupNoTag:fieldNumber value:value];
|
||||
}
|
||||
|
||||
|
||||
- (void) writeMessageNoTag:(id<PBMessage>) value {
|
||||
[self writeRawVarint32:[value serializedSize]];
|
||||
[value writeToCodedOutputStream:self];
|
||||
}
|
||||
|
||||
|
||||
/** Write an embedded message field, including tag, to the stream. */
|
||||
- (void) writeMessage:(int32_t) fieldNumber
|
||||
value:(id<PBMessage>) value {
|
||||
[self writeTag:fieldNumber format:PBWireFormatLengthDelimited];
|
||||
[self writeMessageNoTag:value];
|
||||
}
|
||||
|
||||
|
||||
- (void) writeDataNoTag:(NSData*) value {
|
||||
[self writeRawVarint32:(int32_t)value.length];
|
||||
[self writeRawData:value];
|
||||
}
|
||||
|
||||
|
||||
/** Write a {@code bytes} field, including tag, to the stream. */
|
||||
- (void) writeData:(int32_t) fieldNumber value:(NSData*) value {
|
||||
[self writeTag:fieldNumber format:PBWireFormatLengthDelimited];
|
||||
[self writeDataNoTag:value];
|
||||
}
|
||||
|
||||
|
||||
- (void) writeUInt32NoTag:(int32_t) value {
|
||||
[self writeRawVarint32:value];
|
||||
}
|
||||
|
||||
|
||||
/** Write a {@code uint32} field, including tag, to the stream. */
|
||||
- (void) writeUInt32:(int32_t) fieldNumber
|
||||
value:(int32_t) value {
|
||||
[self writeTag:fieldNumber format:PBWireFormatVarint];
|
||||
[self writeUInt32NoTag:value];
|
||||
}
|
||||
|
||||
|
||||
- (void) writeEnumNoTag:(int32_t) value {
|
||||
[self writeRawVarint32:value];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Write an enum field, including tag, to the stream. Caller is responsible
|
||||
* for converting the enum value to its numeric value.
|
||||
*/
|
||||
- (void) writeEnum:(int32_t) fieldNumber
|
||||
value:(int32_t) value {
|
||||
[self writeTag:fieldNumber format:PBWireFormatVarint];
|
||||
[self writeEnumNoTag:value];
|
||||
}
|
||||
|
||||
|
||||
- (void) writeSFixed32NoTag:(int32_t) value {
|
||||
[self writeRawLittleEndian32:value];
|
||||
}
|
||||
|
||||
|
||||
/** Write an {@code sfixed32} field, including tag, to the stream. */
|
||||
- (void) writeSFixed32:(int32_t) fieldNumber
|
||||
value:(int32_t) value {
|
||||
[self writeTag:fieldNumber format:PBWireFormatFixed32];
|
||||
[self writeSFixed32NoTag:value];
|
||||
}
|
||||
|
||||
|
||||
- (void) writeSFixed64NoTag:(int64_t) value {
|
||||
[self writeRawLittleEndian64:value];
|
||||
}
|
||||
|
||||
|
||||
/** Write an {@code sfixed64} field, including tag, to the stream. */
|
||||
- (void) writeSFixed64:(int32_t) fieldNumber
|
||||
value:(int64_t) value {
|
||||
[self writeTag:fieldNumber format:PBWireFormatFixed64];
|
||||
[self writeSFixed64NoTag:value];
|
||||
}
|
||||
|
||||
|
||||
- (void) writeSInt32NoTag:(int32_t) value {
|
||||
[self writeRawVarint32:encodeZigZag32(value)];
|
||||
}
|
||||
|
||||
|
||||
/** Write an {@code sint32} field, including tag, to the stream. */
|
||||
- (void) writeSInt32:(int32_t) fieldNumber
|
||||
value:(int32_t) value {
|
||||
[self writeTag:fieldNumber format:PBWireFormatVarint];
|
||||
[self writeSInt32NoTag:value];
|
||||
}
|
||||
|
||||
|
||||
- (void) writeSInt64NoTag:(int64_t) value {
|
||||
[self writeRawVarint64:encodeZigZag64(value)];
|
||||
}
|
||||
|
||||
|
||||
/** Write an {@code sint64} field, including tag, to the stream. */
|
||||
- (void) writeSInt64:(int32_t) fieldNumber
|
||||
value:(int64_t) value {
|
||||
[self writeTag:fieldNumber format:PBWireFormatVarint];
|
||||
[self writeSInt64NoTag:value];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Write a MessageSet extension field to the stream. For historical reasons,
|
||||
* the wire format differs from normal fields.
|
||||
*/
|
||||
- (void) writeMessageSetExtension:(int32_t) fieldNumber
|
||||
value:(id<PBMessage>) value {
|
||||
[self writeTag:PBWireFormatMessageSetItem format:PBWireFormatStartGroup];
|
||||
[self writeUInt32:PBWireFormatMessageSetTypeId value:fieldNumber];
|
||||
[self writeMessage:PBWireFormatMessageSetMessage value:value];
|
||||
[self writeTag:PBWireFormatMessageSetItem format:PBWireFormatEndGroup];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Write an unparsed MessageSet extension field to the stream. For
|
||||
* historical reasons, the wire format differs from normal fields.
|
||||
*/
|
||||
- (void) writeRawMessageSetExtension:(int32_t) fieldNumber
|
||||
value:(NSData*) value {
|
||||
[self writeTag:PBWireFormatMessageSetItem format:PBWireFormatStartGroup];
|
||||
[self writeUInt32:PBWireFormatMessageSetTypeId value:fieldNumber];
|
||||
[self writeData:PBWireFormatMessageSetMessage value:value];
|
||||
[self writeTag:PBWireFormatMessageSetItem format:PBWireFormatEndGroup];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compute the number of bytes that would be needed to encode a
|
||||
* {@code double} field, including tag.
|
||||
*/
|
||||
int32_t computeDoubleSizeNoTag(Float64 value) {
|
||||
return LITTLE_ENDIAN_64_SIZE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compute the number of bytes that would be needed to encode a
|
||||
* {@code float} field, including tag.
|
||||
*/
|
||||
int32_t computeFloatSizeNoTag(Float32 value) {
|
||||
return LITTLE_ENDIAN_32_SIZE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compute the number of bytes that would be needed to encode a
|
||||
* {@code uint64} field, including tag.
|
||||
*/
|
||||
int32_t computeUInt64SizeNoTag(int64_t value) {
|
||||
return computeRawVarint64Size(value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compute the number of bytes that would be needed to encode an
|
||||
* {@code int64} field, including tag.
|
||||
*/
|
||||
int32_t computeInt64SizeNoTag(int64_t value) {
|
||||
return computeRawVarint64Size(value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compute the number of bytes that would be needed to encode an
|
||||
* {@code int32} field, including tag.
|
||||
*/
|
||||
int32_t computeInt32SizeNoTag(int32_t value) {
|
||||
if (value >= 0) {
|
||||
return computeRawVarint32Size(value);
|
||||
} else {
|
||||
// Must sign-extend.
|
||||
return 10;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compute the number of bytes that would be needed to encode a
|
||||
* {@code fixed64} field, including tag.
|
||||
*/
|
||||
int32_t computeFixed64SizeNoTag(int64_t value) {
|
||||
return LITTLE_ENDIAN_64_SIZE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compute the number of bytes that would be needed to encode a
|
||||
* {@code fixed32} field, including tag.
|
||||
*/
|
||||
int32_t computeFixed32SizeNoTag(int32_t value) {
|
||||
return LITTLE_ENDIAN_32_SIZE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compute the number of bytes that would be needed to encode a
|
||||
* {@code bool} field, including tag.
|
||||
*/
|
||||
int32_t computeBoolSizeNoTag(BOOL value) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compute the number of bytes that would be needed to encode a
|
||||
* {@code string} field, including tag.
|
||||
*/
|
||||
int32_t computeStringSizeNoTag(NSString* value) {
|
||||
NSData* data = [value dataUsingEncoding:NSUTF8StringEncoding];
|
||||
return computeRawVarint32Size((int32_t)data.length) + (int32_t)data.length;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compute the number of bytes that would be needed to encode a
|
||||
* {@code group} field, including tag.
|
||||
*/
|
||||
int32_t computeGroupSizeNoTag(id<PBMessage> value) {
|
||||
return [value serializedSize];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compute the number of bytes that would be needed to encode a
|
||||
* {@code group} field represented by an {@code PBUnknownFieldSet}, including
|
||||
* tag.
|
||||
*/
|
||||
int32_t computeUnknownGroupSizeNoTag(PBUnknownFieldSet* value) {
|
||||
return value.serializedSize;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compute the number of bytes that would be needed to encode an
|
||||
* embedded message field, including tag.
|
||||
*/
|
||||
int32_t computeMessageSizeNoTag(id<PBMessage> value) {
|
||||
int32_t size = [value serializedSize];
|
||||
return computeRawVarint32Size(size) + size;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compute the number of bytes that would be needed to encode a
|
||||
* {@code bytes} field, including tag.
|
||||
*/
|
||||
int32_t computeDataSizeNoTag(NSData* value) {
|
||||
return computeRawVarint32Size((int32_t)value.length) + (int32_t)value.length;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compute the number of bytes that would be needed to encode a
|
||||
* {@code uint32} field, including tag.
|
||||
*/
|
||||
int32_t computeUInt32SizeNoTag(int32_t value) {
|
||||
return computeRawVarint32Size(value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compute the number of bytes that would be needed to encode an
|
||||
* enum field, including tag. Caller is responsible for converting the
|
||||
* enum value to its numeric value.
|
||||
*/
|
||||
int32_t computeEnumSizeNoTag(int32_t value) {
|
||||
return computeRawVarint32Size(value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compute the number of bytes that would be needed to encode an
|
||||
* {@code sfixed32} field, including tag.
|
||||
*/
|
||||
int32_t computeSFixed32SizeNoTag(int32_t value) {
|
||||
return LITTLE_ENDIAN_32_SIZE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compute the number of bytes that would be needed to encode an
|
||||
* {@code sfixed64} field, including tag.
|
||||
*/
|
||||
int32_t computeSFixed64SizeNoTag(int64_t value) {
|
||||
return LITTLE_ENDIAN_64_SIZE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compute the number of bytes that would be needed to encode an
|
||||
* {@code sint32} field, including tag.
|
||||
*/
|
||||
int32_t computeSInt32SizeNoTag(int32_t value) {
|
||||
return computeRawVarint32Size(encodeZigZag32(value));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compute the number of bytes that would be needed to encode an
|
||||
* {@code sint64} field, including tag.
|
||||
*/
|
||||
int32_t computeSInt64SizeNoTag(int64_t value) {
|
||||
return computeRawVarint64Size(encodeZigZag64(value));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compute the number of bytes that would be needed to encode a
|
||||
* {@code double} field, including tag.
|
||||
*/
|
||||
int32_t computeDoubleSize(int32_t fieldNumber, Float64 value) {
|
||||
return computeTagSize(fieldNumber) + computeDoubleSizeNoTag(value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compute the number of bytes that would be needed to encode a
|
||||
* {@code float} field, including tag.
|
||||
*/
|
||||
int32_t computeFloatSize(int32_t fieldNumber, Float32 value) {
|
||||
return computeTagSize(fieldNumber) + computeFloatSizeNoTag(value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compute the number of bytes that would be needed to encode a
|
||||
* {@code uint64} field, including tag.
|
||||
*/
|
||||
int32_t computeUInt64Size(int32_t fieldNumber, int64_t value) {
|
||||
return computeTagSize(fieldNumber) + computeUInt64SizeNoTag(value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compute the number of bytes that would be needed to encode an
|
||||
* {@code int64} field, including tag.
|
||||
*/
|
||||
int32_t computeInt64Size(int32_t fieldNumber, int64_t value) {
|
||||
return computeTagSize(fieldNumber) + computeInt64SizeNoTag(value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compute the number of bytes that would be needed to encode an
|
||||
* {@code int32} field, including tag.
|
||||
*/
|
||||
int32_t computeInt32Size(int32_t fieldNumber, int32_t value) {
|
||||
return computeTagSize(fieldNumber) + computeInt32SizeNoTag(value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compute the number of bytes that would be needed to encode a
|
||||
* {@code fixed64} field, including tag.
|
||||
*/
|
||||
int32_t computeFixed64Size(int32_t fieldNumber, int64_t value) {
|
||||
return computeTagSize(fieldNumber) + computeFixed64SizeNoTag(value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compute the number of bytes that would be needed to encode a
|
||||
* {@code fixed32} field, including tag.
|
||||
*/
|
||||
int32_t computeFixed32Size(int32_t fieldNumber, int32_t value) {
|
||||
return computeTagSize(fieldNumber) + computeFixed32SizeNoTag(value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compute the number of bytes that would be needed to encode a
|
||||
* {@code bool} field, including tag.
|
||||
*/
|
||||
int32_t computeBoolSize(int32_t fieldNumber, BOOL value) {
|
||||
return computeTagSize(fieldNumber) + computeBoolSizeNoTag(value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compute the number of bytes that would be needed to encode a
|
||||
* {@code string} field, including tag.
|
||||
*/
|
||||
int32_t computeStringSize(int32_t fieldNumber, NSString* value) {
|
||||
return computeTagSize(fieldNumber) + computeStringSizeNoTag(value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compute the number of bytes that would be needed to encode a
|
||||
* {@code group} field, including tag.
|
||||
*/
|
||||
int32_t computeGroupSize(int32_t fieldNumber, id<PBMessage> value) {
|
||||
return computeTagSize(fieldNumber) * 2 + computeGroupSizeNoTag(value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compute the number of bytes that would be needed to encode a
|
||||
* {@code group} field represented by an {@code PBUnknownFieldSet}, including
|
||||
* tag.
|
||||
*/
|
||||
int32_t computeUnknownGroupSize(int32_t fieldNumber,
|
||||
PBUnknownFieldSet* value) {
|
||||
return computeTagSize(fieldNumber) * 2 + computeUnknownGroupSizeNoTag(value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compute the number of bytes that would be needed to encode an
|
||||
* embedded message field, including tag.
|
||||
*/
|
||||
int32_t computeMessageSize(int32_t fieldNumber, id<PBMessage> value) {
|
||||
return computeTagSize(fieldNumber) + computeMessageSizeNoTag(value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compute the number of bytes that would be needed to encode a
|
||||
* {@code bytes} field, including tag.
|
||||
*/
|
||||
int32_t computeDataSize(int32_t fieldNumber, NSData* value) {
|
||||
return computeTagSize(fieldNumber) + computeDataSizeNoTag(value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compute the number of bytes that would be needed to encode a
|
||||
* {@code uint32} field, including tag.
|
||||
*/
|
||||
int32_t computeUInt32Size(int32_t fieldNumber, int32_t value) {
|
||||
return computeTagSize(fieldNumber) + computeUInt32SizeNoTag(value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compute the number of bytes that would be needed to encode an
|
||||
* enum field, including tag. Caller is responsible for converting the
|
||||
* enum value to its numeric value.
|
||||
*/
|
||||
int32_t computeEnumSize(int32_t fieldNumber, int32_t value) {
|
||||
return computeTagSize(fieldNumber) + computeEnumSizeNoTag(value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compute the number of bytes that would be needed to encode an
|
||||
* {@code sfixed32} field, including tag.
|
||||
*/
|
||||
int32_t computeSFixed32Size(int32_t fieldNumber, int32_t value) {
|
||||
return computeTagSize(fieldNumber) + computeSFixed32SizeNoTag(value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compute the number of bytes that would be needed to encode an
|
||||
* {@code sfixed64} field, including tag.
|
||||
*/
|
||||
int32_t computeSFixed64Size(int32_t fieldNumber, int64_t value) {
|
||||
return computeTagSize(fieldNumber) + computeSFixed64SizeNoTag(value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compute the number of bytes that would be needed to encode an
|
||||
* {@code sint32} field, including tag.
|
||||
*/
|
||||
int32_t computeSInt32Size(int32_t fieldNumber, int32_t value) {
|
||||
return computeTagSize(fieldNumber) + computeSInt32SizeNoTag(value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compute the number of bytes that would be needed to encode an
|
||||
* {@code sint64} field, including tag.
|
||||
*/
|
||||
int32_t computeSInt64Size(int32_t fieldNumber, int64_t value) {
|
||||
return computeTagSize(fieldNumber) +
|
||||
computeRawVarint64Size(encodeZigZag64(value));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compute the number of bytes that would be needed to encode a
|
||||
* MessageSet extension to the stream. For historical reasons,
|
||||
* the wire format differs from normal fields.
|
||||
*/
|
||||
int32_t computeMessageSetExtensionSize(int32_t fieldNumber, id<PBMessage> value) {
|
||||
return computeTagSize(PBWireFormatMessageSetItem) * 2 +
|
||||
computeUInt32Size(PBWireFormatMessageSetTypeId, fieldNumber) +
|
||||
computeMessageSize(PBWireFormatMessageSetMessage, value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compute the number of bytes that would be needed to encode an
|
||||
* unparsed MessageSet extension field to the stream. For
|
||||
* historical reasons, the wire format differs from normal fields.
|
||||
*/
|
||||
int32_t computeRawMessageSetExtensionSize(int32_t fieldNumber, NSData* value) {
|
||||
return computeTagSize(PBWireFormatMessageSetItem) * 2 +
|
||||
computeUInt32Size(PBWireFormatMessageSetTypeId, fieldNumber) +
|
||||
computeDataSize(PBWireFormatMessageSetMessage, value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Internal helper that writes the current buffer to the output. The
|
||||
* buffer position is reset to its initial value when this returns.
|
||||
*/
|
||||
- (void) refreshBuffer {
|
||||
if (output == nil) {
|
||||
// We're writing to a single buffer.
|
||||
@throw [NSException exceptionWithName:@"OutOfSpace" reason:@"" userInfo:nil];
|
||||
}
|
||||
|
||||
|
||||
[output write:buffer.bytes maxLength:(NSUInteger)position];
|
||||
position = 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Flushes the stream and forces any buffered bytes to be written. This
|
||||
* does not flush the underlying OutputStream.
|
||||
*/
|
||||
- (void) flush {
|
||||
if (output != nil) {
|
||||
[self refreshBuffer];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* If writing to a flat array, return the space left in the array.
|
||||
* Otherwise, throws {@code UnsupportedOperationException}.
|
||||
*/
|
||||
- (int32_t) spaceLeft {
|
||||
if (output == nil) {
|
||||
return (int32_t)buffer.length - position;
|
||||
} else {
|
||||
@throw [NSException exceptionWithName:@"UnsupportedOperation"
|
||||
reason:@"spaceLeft() can only be called on CodedOutputStreams that are writing to a flat array."
|
||||
userInfo:nil];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Verifies that {@link #spaceLeft()} returns zero. It's common to create
|
||||
* a byte array that is exactly big enough to hold a message, then write to
|
||||
* it with a {@code PBCodedOutputStream}. Calling {@code checkNoSpaceLeft()}
|
||||
* after writing verifies that the message was actually as big as expected,
|
||||
* which can help catch bugs.
|
||||
*/
|
||||
- (void) checkNoSpaceLeft {
|
||||
if (self.spaceLeft != 0) {
|
||||
@throw [NSException exceptionWithName:@"IllegalState" reason:@"Did not write as much data as expected." userInfo:nil];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** Write a single byte. */
|
||||
- (void) writeRawByte:(uint8_t) value {
|
||||
if (position == (int32_t)buffer.length) {
|
||||
[self refreshBuffer];
|
||||
}
|
||||
|
||||
((uint8_t*)buffer.mutableBytes)[position++] = value;
|
||||
}
|
||||
|
||||
|
||||
/** Write an array of bytes. */
|
||||
- (void) writeRawData:(NSData*) data {
|
||||
[self writeRawData:data offset:0 length:(int32_t)data.length];
|
||||
}
|
||||
|
||||
|
||||
- (void) writeRawData:(NSData*) value offset:(int32_t) offset length:(int32_t) length {
|
||||
if ((int32_t)buffer.length - position >= length) {
|
||||
// We have room in the current buffer.
|
||||
memcpy(((uint8_t*)buffer.mutableBytes) + position, ((uint8_t*)value.bytes) + offset, length);
|
||||
position += length;
|
||||
} else {
|
||||
// Write extends past current buffer. Fill the rest of this buffer and flush.
|
||||
int32_t bytesWritten = (int32_t)buffer.length - position;
|
||||
memcpy(((uint8_t*)buffer.mutableBytes) + position, ((uint8_t*)value.bytes) + offset, bytesWritten);
|
||||
offset += bytesWritten;
|
||||
length -= bytesWritten;
|
||||
position = (int32_t)buffer.length;
|
||||
[self refreshBuffer];
|
||||
|
||||
// Now deal with the rest.
|
||||
// Since we have an output stream, this is our buffer
|
||||
// and buffer offset == 0
|
||||
if (length <= (int32_t)buffer.length) {
|
||||
// Fits in new buffer.
|
||||
memcpy((uint8_t*)buffer.mutableBytes, ((uint8_t*)value.bytes) + offset, length);
|
||||
position = length;
|
||||
} else {
|
||||
// Write is very big. Let's do it all at once.
|
||||
[output write:((uint8_t*) value.bytes) + offset maxLength:(NSUInteger)length];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** Encode and write a tag. */
|
||||
- (void) writeTag:(int32_t) fieldNumber
|
||||
format:(int32_t) format {
|
||||
[self writeRawVarint32:PBWireFormatMakeTag(fieldNumber, format)];
|
||||
}
|
||||
|
||||
|
||||
/** Compute the number of bytes that would be needed to encode a tag. */
|
||||
int32_t computeTagSize(int32_t fieldNumber) {
|
||||
return computeRawVarint32Size(PBWireFormatMakeTag(fieldNumber, 0));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Encode and write a varint. {@code value} is treated as
|
||||
* unsigned, so it won't be sign-extended if negative.
|
||||
*/
|
||||
- (void) writeRawVarint32:(int32_t) value {
|
||||
while (YES) {
|
||||
if ((value & ~0x7F) == 0) {
|
||||
[self writeRawByte:(uint8_t)value];
|
||||
return;
|
||||
} else {
|
||||
[self writeRawByte:((value & 0x7F) | 0x80)];
|
||||
value = logicalRightShift32(value, 7);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compute the number of bytes that would be needed to encode a varint.
|
||||
* {@code value} is treated as unsigned, so it won't be sign-extended if
|
||||
* negative.
|
||||
*/
|
||||
int32_t computeRawVarint32Size(int32_t value) {
|
||||
if ((value & (0xffffffffLL << 7)) == 0) return 1;
|
||||
if ((value & (0xffffffffLL << 14)) == 0) return 2;
|
||||
if ((value & (0xffffffffLL << 21)) == 0) return 3;
|
||||
if ((value & (0xffffffffLL << 28)) == 0) return 4;
|
||||
return 5;
|
||||
}
|
||||
|
||||
|
||||
/** Encode and write a varint. */
|
||||
- (void) writeRawVarint64:(int64_t) value{
|
||||
while (YES) {
|
||||
if ((value & ~0x7FL) == 0) {
|
||||
[self writeRawByte:(uint8_t)((int32_t) value)];
|
||||
return;
|
||||
} else {
|
||||
[self writeRawByte:(uint8_t)(((int32_t) value & 0x7F) | 0x80)];
|
||||
value = logicalRightShift64(value, 7);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** Compute the number of bytes that would be needed to encode a varint. */
|
||||
int32_t computeRawVarint64Size(int64_t value) {
|
||||
if (((uint64_t)value & (0xffffffffffffffffULL << 7)) == 0) return 1;
|
||||
if (((uint64_t)value & (0xffffffffffffffffULL << 14)) == 0) return 2;
|
||||
if (((uint64_t)value & (0xffffffffffffffffULL << 21)) == 0) return 3;
|
||||
if (((uint64_t)value & (0xffffffffffffffffULL << 28)) == 0) return 4;
|
||||
if (((uint64_t)value & (0xffffffffffffffffULL << 35)) == 0) return 5;
|
||||
if (((uint64_t)value & (0xffffffffffffffffULL << 42)) == 0) return 6;
|
||||
if (((uint64_t)value & (0xffffffffffffffffULL << 49)) == 0) return 7;
|
||||
if (((uint64_t)value & (0xffffffffffffffffULL << 56)) == 0) return 8;
|
||||
if (((uint64_t)value & (0xffffffffffffffffULL << 63)) == 0) return 9;
|
||||
return 10;
|
||||
}
|
||||
|
||||
|
||||
/** Write a little-endian 32-bit integer. */
|
||||
- (void) writeRawLittleEndian32:(int32_t) value {
|
||||
[self writeRawByte:((value ) & 0xFF)];
|
||||
[self writeRawByte:((value >> 8) & 0xFF)];
|
||||
[self writeRawByte:((value >> 16) & 0xFF)];
|
||||
[self writeRawByte:((value >> 24) & 0xFF)];
|
||||
}
|
||||
|
||||
|
||||
/** Write a little-endian 64-bit integer. */
|
||||
- (void) writeRawLittleEndian64:(int64_t) value {
|
||||
[self writeRawByte:((int32_t)(value ) & 0xFF)];
|
||||
[self writeRawByte:((int32_t)(value >> 8) & 0xFF)];
|
||||
[self writeRawByte:((int32_t)(value >> 16) & 0xFF)];
|
||||
[self writeRawByte:((int32_t)(value >> 24) & 0xFF)];
|
||||
[self writeRawByte:((int32_t)(value >> 32) & 0xFF)];
|
||||
[self writeRawByte:((int32_t)(value >> 40) & 0xFF)];
|
||||
[self writeRawByte:((int32_t)(value >> 48) & 0xFF)];
|
||||
[self writeRawByte:((int32_t)(value >> 56) & 0xFF)];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Encode a ZigZag-encoded 32-bit value. ZigZag encodes signed integers
|
||||
* into values that can be efficiently encoded with varint. (Otherwise,
|
||||
* negative values must be sign-extended to 64 bits to be varint encoded,
|
||||
* thus always taking 10 bytes on the wire.)
|
||||
*
|
||||
* @param n A signed 32-bit integer.
|
||||
* @return An unsigned 32-bit integer, stored in a signed int
|
||||
*/
|
||||
int32_t encodeZigZag32(int32_t n) {
|
||||
// Note: the right-shift must be arithmetic
|
||||
return (n << 1) ^ (n >> 31);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Encode a ZigZag-encoded 64-bit value. ZigZag encodes signed integers
|
||||
* into values that can be efficiently encoded with varint. (Otherwise,
|
||||
* negative values must be sign-extended to 64 bits to be varint encoded,
|
||||
* thus always taking 10 bytes on the wire.)
|
||||
*
|
||||
* @param n A signed 64-bit integer.
|
||||
* @return An unsigned 64-bit integer, stored in a signed int
|
||||
*/
|
||||
int64_t encodeZigZag64(int64_t n) {
|
||||
// Note: the right-shift must be arithmetic
|
||||
return (n << 1) ^ (n >> 63);
|
||||
}
|
||||
|
||||
@end
|
|
@ -1,62 +0,0 @@
|
|||
// 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 "ExtensionField.h"
|
||||
|
||||
typedef enum {
|
||||
PBExtensionTypeBool,
|
||||
PBExtensionTypeFixed32,
|
||||
PBExtensionTypeSFixed32,
|
||||
PBExtensionTypeFloat,
|
||||
PBExtensionTypeFixed64,
|
||||
PBExtensionTypeSFixed64,
|
||||
PBExtensionTypeDouble,
|
||||
PBExtensionTypeInt32,
|
||||
PBExtensionTypeInt64,
|
||||
PBExtensionTypeSInt32,
|
||||
PBExtensionTypeSInt64,
|
||||
PBExtensionTypeUInt32,
|
||||
PBExtensionTypeUInt64,
|
||||
PBExtensionTypeBytes,
|
||||
PBExtensionTypeString,
|
||||
PBExtensionTypeMessage,
|
||||
PBExtensionTypeGroup,
|
||||
PBExtensionTypeEnum
|
||||
} PBExtensionType;
|
||||
|
||||
@interface PBConcreteExtensionField : NSObject<PBExtensionField> {
|
||||
@private
|
||||
PBExtensionType type;
|
||||
|
||||
Class extendedClass;
|
||||
int32_t fieldNumber;
|
||||
id defaultValue;
|
||||
|
||||
Class messageOrGroupClass;
|
||||
|
||||
BOOL isRepeated;
|
||||
BOOL isPacked;
|
||||
BOOL isMessageSetWireFormat;
|
||||
}
|
||||
|
||||
+ (PBConcreteExtensionField*) extensionWithType:(PBExtensionType) type
|
||||
extendedClass:(Class) extendedClass
|
||||
fieldNumber:(int32_t) fieldNumber
|
||||
defaultValue:(id) defaultValue
|
||||
messageOrGroupClass:(Class) messageOrGroupClass
|
||||
isRepeated:(BOOL) isRepeated
|
||||
isPacked:(BOOL) isPacked
|
||||
isMessageSetWireFormat:(BOOL) isMessageSetWireFormat;
|
||||
|
||||
@end
|
|
@ -1,543 +0,0 @@
|
|||
// 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 "ConcreteExtensionField.h"
|
||||
#import "CodedOutputStream.h"
|
||||
#import "CodedInputStream.h"
|
||||
#import "Message_Builder.h"
|
||||
#import "Message.h"
|
||||
#import "ExtendableMessage_Builder.h"
|
||||
|
||||
@interface PBConcreteExtensionField()
|
||||
@property PBExtensionType type;
|
||||
@property Class extendedClass;
|
||||
@property int32_t fieldNumber;
|
||||
@property (retain) id defaultValue;
|
||||
@property Class messageOrGroupClass;
|
||||
@property BOOL isRepeated;
|
||||
@property BOOL isPacked;
|
||||
@property BOOL isMessageSetWireFormat;
|
||||
@end
|
||||
|
||||
@implementation PBConcreteExtensionField
|
||||
|
||||
@synthesize type;
|
||||
@synthesize extendedClass;
|
||||
@synthesize fieldNumber;
|
||||
@synthesize defaultValue;
|
||||
@synthesize messageOrGroupClass;
|
||||
@synthesize isRepeated;
|
||||
@synthesize isPacked;
|
||||
@synthesize isMessageSetWireFormat;
|
||||
|
||||
- (void) dealloc {
|
||||
self.type = 0;
|
||||
self.extendedClass = nil;
|
||||
self.fieldNumber = 0;
|
||||
self.defaultValue = nil;
|
||||
self.messageOrGroupClass = nil;
|
||||
self.isRepeated = NO;
|
||||
self.isPacked = NO;
|
||||
self.isMessageSetWireFormat = NO;
|
||||
}
|
||||
|
||||
|
||||
- (id) initWithType:(PBExtensionType) type_
|
||||
extendedClass:(Class) extendedClass_
|
||||
fieldNumber:(int32_t) fieldNumber_
|
||||
defaultValue:(id) defaultValue_
|
||||
messageOrGroupClass:(Class) messageOrGroupClass_
|
||||
isRepeated:(BOOL) isRepeated_
|
||||
isPacked:(BOOL) isPacked_
|
||||
isMessageSetWireFormat:(BOOL) isMessageSetWireFormat_ {
|
||||
if ((self = [super init])) {
|
||||
self.type = type_;
|
||||
self.extendedClass = extendedClass_;
|
||||
self.fieldNumber = fieldNumber_;
|
||||
self.defaultValue = defaultValue_;
|
||||
self.messageOrGroupClass = messageOrGroupClass_;
|
||||
self.isRepeated = isRepeated_;
|
||||
self.isPacked = isPacked_;
|
||||
self.isMessageSetWireFormat = isMessageSetWireFormat_;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
+ (PBConcreteExtensionField*) extensionWithType:(PBExtensionType) type
|
||||
extendedClass:(Class) extendedClass
|
||||
fieldNumber:(int32_t) fieldNumber
|
||||
defaultValue:(id) defaultValue
|
||||
messageOrGroupClass:(Class) messageOrGroupClass
|
||||
isRepeated:(BOOL) isRepeated
|
||||
isPacked:(BOOL) isPacked
|
||||
isMessageSetWireFormat:(BOOL) isMessageSetWireFormat {
|
||||
return [[PBConcreteExtensionField alloc] initWithType:type
|
||||
extendedClass:extendedClass
|
||||
fieldNumber:fieldNumber
|
||||
defaultValue:defaultValue
|
||||
messageOrGroupClass:messageOrGroupClass
|
||||
isRepeated:isRepeated
|
||||
isPacked:isPacked
|
||||
isMessageSetWireFormat:isMessageSetWireFormat];
|
||||
}
|
||||
|
||||
|
||||
- (PBWireFormat) wireType {
|
||||
if (isPacked) {
|
||||
return PBWireFormatLengthDelimited;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case PBExtensionTypeBool: return PBWireFormatVarint;
|
||||
case PBExtensionTypeFixed32: return PBWireFormatFixed32;
|
||||
case PBExtensionTypeSFixed32: return PBWireFormatFixed32;
|
||||
case PBExtensionTypeFloat: return PBWireFormatFixed32;
|
||||
case PBExtensionTypeFixed64: return PBWireFormatFixed64;
|
||||
case PBExtensionTypeSFixed64: return PBWireFormatFixed64;
|
||||
case PBExtensionTypeDouble: return PBWireFormatFixed64;
|
||||
case PBExtensionTypeInt32: return PBWireFormatVarint;
|
||||
case PBExtensionTypeInt64: return PBWireFormatVarint;
|
||||
case PBExtensionTypeSInt32: return PBWireFormatVarint;
|
||||
case PBExtensionTypeSInt64: return PBWireFormatVarint;
|
||||
case PBExtensionTypeUInt32: return PBWireFormatVarint;
|
||||
case PBExtensionTypeUInt64: return PBWireFormatVarint;
|
||||
case PBExtensionTypeBytes: return PBWireFormatLengthDelimited;
|
||||
case PBExtensionTypeString: return PBWireFormatLengthDelimited;
|
||||
case PBExtensionTypeMessage: return PBWireFormatLengthDelimited;
|
||||
case PBExtensionTypeGroup: return PBWireFormatStartGroup;
|
||||
case PBExtensionTypeEnum: return PBWireFormatVarint;
|
||||
}
|
||||
|
||||
@throw [NSException exceptionWithName:@"InternalError" reason:@"" userInfo:nil];
|
||||
}
|
||||
|
||||
|
||||
BOOL typeIsFixedSize(PBExtensionType type);
|
||||
BOOL typeIsFixedSize(PBExtensionType type) {
|
||||
switch (type) {
|
||||
case PBExtensionTypeBool:
|
||||
case PBExtensionTypeFixed32:
|
||||
case PBExtensionTypeSFixed32:
|
||||
case PBExtensionTypeFloat:
|
||||
case PBExtensionTypeFixed64:
|
||||
case PBExtensionTypeSFixed64:
|
||||
case PBExtensionTypeDouble:
|
||||
return YES;
|
||||
default:
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int32_t typeSize(PBExtensionType type);
|
||||
int32_t typeSize(PBExtensionType type) {
|
||||
switch (type) {
|
||||
case PBExtensionTypeBool:
|
||||
return 1;
|
||||
case PBExtensionTypeFixed32:
|
||||
case PBExtensionTypeSFixed32:
|
||||
case PBExtensionTypeFloat:
|
||||
return 4;
|
||||
case PBExtensionTypeFixed64:
|
||||
case PBExtensionTypeSFixed64:
|
||||
case PBExtensionTypeDouble:
|
||||
return 8;
|
||||
default:
|
||||
@throw [NSException exceptionWithName:@"InternalError" reason:@"" userInfo:nil];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (void) writeSingleValue:(id) value
|
||||
includingTagToCodedOutputStream:(PBCodedOutputStream*) output {
|
||||
switch (type) {
|
||||
case PBExtensionTypeBool:
|
||||
[output writeBool:fieldNumber value:[value boolValue]];
|
||||
return;
|
||||
case PBExtensionTypeFixed32:
|
||||
[output writeFixed32:fieldNumber value:[value intValue]];
|
||||
return;
|
||||
case PBExtensionTypeSFixed32:
|
||||
[output writeSFixed32:fieldNumber value:[value intValue]];
|
||||
return;
|
||||
case PBExtensionTypeFloat:
|
||||
[output writeFloat:fieldNumber value:[value floatValue]];
|
||||
return;
|
||||
case PBExtensionTypeFixed64:
|
||||
[output writeFixed64:fieldNumber value:[value longLongValue]];
|
||||
return;
|
||||
case PBExtensionTypeSFixed64:
|
||||
[output writeSFixed64:fieldNumber value:[value longLongValue]];
|
||||
return;
|
||||
case PBExtensionTypeDouble:
|
||||
[output writeDouble:fieldNumber value:[value doubleValue]];
|
||||
return;
|
||||
case PBExtensionTypeInt32:
|
||||
[output writeInt32:fieldNumber value:[value intValue]];
|
||||
return;
|
||||
case PBExtensionTypeInt64:
|
||||
[output writeInt64:fieldNumber value:[value longLongValue]];
|
||||
return;
|
||||
case PBExtensionTypeSInt32:
|
||||
[output writeSInt32:fieldNumber value:[value intValue]];
|
||||
return;
|
||||
case PBExtensionTypeSInt64:
|
||||
[output writeSInt64:fieldNumber value:[value longLongValue]];
|
||||
return;
|
||||
case PBExtensionTypeUInt32:
|
||||
[output writeUInt32:fieldNumber value:[value intValue]];
|
||||
return;
|
||||
case PBExtensionTypeUInt64:
|
||||
[output writeUInt64:fieldNumber value:[value longLongValue]];
|
||||
return;
|
||||
case PBExtensionTypeBytes:
|
||||
[output writeData:fieldNumber value:value];
|
||||
return;
|
||||
case PBExtensionTypeString:
|
||||
[output writeString:fieldNumber value:value];
|
||||
return;
|
||||
case PBExtensionTypeGroup:
|
||||
[output writeGroup:fieldNumber value:value];
|
||||
return;
|
||||
case PBExtensionTypeEnum:
|
||||
[output writeEnum:fieldNumber value:[value intValue]];
|
||||
return;
|
||||
case PBExtensionTypeMessage:
|
||||
if (isMessageSetWireFormat) {
|
||||
[output writeMessageSetExtension:fieldNumber value:value];
|
||||
} else {
|
||||
[output writeMessage:fieldNumber value:value];
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@throw [NSException exceptionWithName:@"InternalError" reason:@"" userInfo:nil];
|
||||
}
|
||||
|
||||
|
||||
- (void) writeSingleValue:(id) value
|
||||
noTagToCodedOutputStream:(PBCodedOutputStream*) output {
|
||||
switch (type) {
|
||||
case PBExtensionTypeBool:
|
||||
[output writeBoolNoTag:[value boolValue]];
|
||||
return;
|
||||
case PBExtensionTypeFixed32:
|
||||
[output writeFixed32NoTag:[value intValue]];
|
||||
return;
|
||||
case PBExtensionTypeSFixed32:
|
||||
[output writeSFixed32NoTag:[value intValue]];
|
||||
return;
|
||||
case PBExtensionTypeFloat:
|
||||
[output writeFloatNoTag:[value floatValue]];
|
||||
return;
|
||||
case PBExtensionTypeFixed64:
|
||||
[output writeFixed64NoTag:[value longLongValue]];
|
||||
return;
|
||||
case PBExtensionTypeSFixed64:
|
||||
[output writeSFixed64NoTag:[value longLongValue]];
|
||||
return;
|
||||
case PBExtensionTypeDouble:
|
||||
[output writeDoubleNoTag:[value doubleValue]];
|
||||
return;
|
||||
case PBExtensionTypeInt32:
|
||||
[output writeInt32NoTag:[value intValue]];
|
||||
return;
|
||||
case PBExtensionTypeInt64:
|
||||
[output writeInt64NoTag:[value longLongValue]];
|
||||
return;
|
||||
case PBExtensionTypeSInt32:
|
||||
[output writeSInt32NoTag:[value intValue]];
|
||||
return;
|
||||
case PBExtensionTypeSInt64:
|
||||
[output writeSInt64NoTag:[value longLongValue]];
|
||||
return;
|
||||
case PBExtensionTypeUInt32:
|
||||
[output writeUInt32NoTag:[value intValue]];
|
||||
return;
|
||||
case PBExtensionTypeUInt64:
|
||||
[output writeUInt64NoTag:[value longLongValue]];
|
||||
return;
|
||||
case PBExtensionTypeBytes:
|
||||
[output writeDataNoTag:value];
|
||||
return;
|
||||
case PBExtensionTypeString:
|
||||
[output writeStringNoTag:value];
|
||||
return;
|
||||
case PBExtensionTypeGroup:
|
||||
[output writeGroupNoTag:fieldNumber value:value];
|
||||
return;
|
||||
case PBExtensionTypeEnum:
|
||||
[output writeEnumNoTag:[value intValue]];
|
||||
return;
|
||||
case PBExtensionTypeMessage:
|
||||
[output writeMessageNoTag:value];
|
||||
return;
|
||||
}
|
||||
|
||||
@throw [NSException exceptionWithName:@"InternalError" reason:@"" userInfo:nil];
|
||||
}
|
||||
|
||||
|
||||
- (int32_t) computeSingleSerializedSizeNoTag:(id) value {
|
||||
switch (type) {
|
||||
case PBExtensionTypeBool: return computeBoolSizeNoTag([value boolValue]);
|
||||
case PBExtensionTypeFixed32: return computeFixed32SizeNoTag([value intValue]);
|
||||
case PBExtensionTypeSFixed32: return computeSFixed32SizeNoTag([value intValue]);
|
||||
case PBExtensionTypeFloat: return computeFloatSizeNoTag([value floatValue]);
|
||||
case PBExtensionTypeFixed64: return computeFixed64SizeNoTag([value longLongValue]);
|
||||
case PBExtensionTypeSFixed64: return computeSFixed64SizeNoTag([value longLongValue]);
|
||||
case PBExtensionTypeDouble: return computeDoubleSizeNoTag([value doubleValue]);
|
||||
case PBExtensionTypeInt32: return computeInt32SizeNoTag([value intValue]);
|
||||
case PBExtensionTypeInt64: return computeInt64SizeNoTag([value longLongValue]);
|
||||
case PBExtensionTypeSInt32: return computeSInt32SizeNoTag([value intValue]);
|
||||
case PBExtensionTypeSInt64: return computeSInt64SizeNoTag([value longLongValue]);
|
||||
case PBExtensionTypeUInt32: return computeUInt32SizeNoTag([value intValue]);
|
||||
case PBExtensionTypeUInt64: return computeUInt64SizeNoTag([value longLongValue]);
|
||||
case PBExtensionTypeBytes: return computeDataSizeNoTag(value);
|
||||
case PBExtensionTypeString: return computeStringSizeNoTag(value);
|
||||
case PBExtensionTypeGroup: return computeGroupSizeNoTag(value);
|
||||
case PBExtensionTypeEnum: return computeEnumSizeNoTag([value intValue]);
|
||||
case PBExtensionTypeMessage: return computeMessageSizeNoTag(value);
|
||||
}
|
||||
|
||||
@throw [NSException exceptionWithName:@"InternalError" reason:@"" userInfo:nil];
|
||||
}
|
||||
|
||||
|
||||
- (int32_t) computeSingleSerializedSizeIncludingTag:(id) value {
|
||||
switch (type) {
|
||||
case PBExtensionTypeBool: return computeBoolSize(fieldNumber, [value boolValue]);
|
||||
case PBExtensionTypeFixed32: return computeFixed32Size(fieldNumber, [value intValue]);
|
||||
case PBExtensionTypeSFixed32: return computeSFixed32Size(fieldNumber, [value intValue]);
|
||||
case PBExtensionTypeFloat: return computeFloatSize(fieldNumber, [value floatValue]);
|
||||
case PBExtensionTypeFixed64: return computeFixed64Size(fieldNumber, [value longLongValue]);
|
||||
case PBExtensionTypeSFixed64: return computeSFixed64Size(fieldNumber, [value longLongValue]);
|
||||
case PBExtensionTypeDouble: return computeDoubleSize(fieldNumber, [value doubleValue]);
|
||||
case PBExtensionTypeInt32: return computeInt32Size(fieldNumber, [value intValue]);
|
||||
case PBExtensionTypeInt64: return computeInt64Size(fieldNumber, [value longLongValue]);
|
||||
case PBExtensionTypeSInt32: return computeSInt32Size(fieldNumber, [value intValue]);
|
||||
case PBExtensionTypeSInt64: return computeSInt64Size(fieldNumber, [value longLongValue]);
|
||||
case PBExtensionTypeUInt32: return computeUInt32Size(fieldNumber, [value intValue]);
|
||||
case PBExtensionTypeUInt64: return computeUInt64Size(fieldNumber, [value longLongValue]);
|
||||
case PBExtensionTypeBytes: return computeDataSize(fieldNumber, value);
|
||||
case PBExtensionTypeString: return computeStringSize(fieldNumber, value);
|
||||
case PBExtensionTypeGroup: return computeGroupSize(fieldNumber, value);
|
||||
case PBExtensionTypeEnum: return computeEnumSize(fieldNumber, [value intValue]);
|
||||
case PBExtensionTypeMessage:
|
||||
if (isMessageSetWireFormat) {
|
||||
return computeMessageSetExtensionSize(fieldNumber, value);
|
||||
} else {
|
||||
return computeMessageSize(fieldNumber, value);
|
||||
}
|
||||
}
|
||||
|
||||
@throw [NSException exceptionWithName:@"InternalError" reason:@"" userInfo:nil];
|
||||
}
|
||||
|
||||
|
||||
- (void) writeRepeatedValues:(NSArray*) values
|
||||
includingTagsToCodedOutputStream:(PBCodedOutputStream*) output {
|
||||
if (isPacked) {
|
||||
[output writeTag:fieldNumber format:PBWireFormatLengthDelimited];
|
||||
int32_t dataSize = 0;
|
||||
if (typeIsFixedSize(type)) {
|
||||
dataSize = (int32_t)values.count * typeSize(type);
|
||||
} else {
|
||||
for (id value in values) {
|
||||
dataSize += [self computeSingleSerializedSizeNoTag:value];
|
||||
}
|
||||
}
|
||||
[output writeRawVarint32:dataSize];
|
||||
for (id value in values) {
|
||||
[self writeSingleValue:value noTagToCodedOutputStream:output];
|
||||
}
|
||||
} else {
|
||||
for (id value in values) {
|
||||
[self writeSingleValue:value includingTagToCodedOutputStream:output];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (void) writeValue:(id) value includingTagToCodedOutputStream:(PBCodedOutputStream*) output {
|
||||
if (isRepeated) {
|
||||
[self writeRepeatedValues:value includingTagsToCodedOutputStream:output];
|
||||
} else {
|
||||
[self writeSingleValue:value includingTagToCodedOutputStream:output];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (int32_t) computeRepeatedSerializedSizeIncludingTags:(NSArray*) values {
|
||||
if (isPacked) {
|
||||
int32_t size = 0;
|
||||
if (typeIsFixedSize(type)) {
|
||||
size = (int32_t)values.count * typeSize(type);
|
||||
} else {
|
||||
for (id value in values) {
|
||||
size += [self computeSingleSerializedSizeNoTag:value];
|
||||
}
|
||||
}
|
||||
return size + computeTagSize(fieldNumber) + computeRawVarint32Size(size);
|
||||
} else {
|
||||
int32_t size = 0;
|
||||
for (id value in values) {
|
||||
size += [self computeSingleSerializedSizeIncludingTag:value];
|
||||
}
|
||||
return size;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (int32_t) computeSerializedSizeIncludingTag:(id) value {
|
||||
if (isRepeated) {
|
||||
return [self computeRepeatedSerializedSizeIncludingTags:value];
|
||||
} else {
|
||||
return [self computeSingleSerializedSizeIncludingTag:value];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (void) mergeMessageSetExtentionFromCodedInputStream:(PBCodedInputStream*) input
|
||||
unknownFields:(PBUnknownFieldSet_Builder*) unknownFields {
|
||||
@throw [NSException exceptionWithName:@"NYI" reason:@"" userInfo:nil];
|
||||
|
||||
// The wire format for MessageSet is:
|
||||
// message MessageSet {
|
||||
// repeated group Item = 1 {
|
||||
// required int32 typeId = 2;
|
||||
// required bytes message = 3;
|
||||
// }
|
||||
// }
|
||||
// "typeId" is the extension's field number. The extension can only be
|
||||
// a message type, where "message" contains the encoded bytes of that
|
||||
// message.
|
||||
//
|
||||
// In practice, we will probably never see a MessageSet item in which
|
||||
// the message appears before the type ID, or where either field does not
|
||||
// appear exactly once. However, in theory such cases are valid, so we
|
||||
// should be prepared to accept them.
|
||||
|
||||
//int typeId = 0;
|
||||
// ByteString rawBytes = null;
|
||||
//
|
||||
// while (true) {
|
||||
// final int tag = input.readTag();
|
||||
// if (tag == 0) {
|
||||
// break;
|
||||
// }
|
||||
//
|
||||
// if (tag == WireFormat.MESSAGE_SET_TYPE_ID_TAG) {
|
||||
// typeId = input.readUInt32();
|
||||
// // Zero is not a valid type ID.
|
||||
// if (typeId != 0) {
|
||||
// if (rawBytes != null) {
|
||||
// unknownFields.mergeField(typeId,
|
||||
// UnknownFieldSet.Field.newBuilder()
|
||||
// .addLengthDelimited(rawBytes)
|
||||
// .build());
|
||||
// rawBytes = null;
|
||||
// }
|
||||
// }
|
||||
// } else if (tag == WireFormat.MESSAGE_SET_MESSAGE_TAG) {
|
||||
// if (typeId == 0) {
|
||||
// // We haven't seen a type ID yet, so we have to store the raw bytes
|
||||
// // for now.
|
||||
// rawBytes = input.readBytes();
|
||||
// } else {
|
||||
// unknownFields.mergeField(typeId,
|
||||
// UnknownFieldSet.Field.newBuilder()
|
||||
// .addLengthDelimited(input.readBytes())
|
||||
// .build());
|
||||
// }
|
||||
// } else {
|
||||
// // Unknown fieldNumber. Skip it.
|
||||
// if (!input.skipField(tag)) {
|
||||
// break; // end of group
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// input.checkLastTagWas(WireFormat.MESSAGE_SET_ITEM_END_TAG);
|
||||
}
|
||||
|
||||
|
||||
- (id) readSingleValueFromCodedInputStream:(PBCodedInputStream*) input
|
||||
extensionRegistry:(PBExtensionRegistry*) extensionRegistry {
|
||||
switch (type) {
|
||||
case PBExtensionTypeBool: return [NSNumber numberWithBool:[input readBool]];
|
||||
case PBExtensionTypeFixed32: return [NSNumber numberWithInt:[input readFixed32]];
|
||||
case PBExtensionTypeSFixed32: return [NSNumber numberWithInt:[input readSFixed32]];
|
||||
case PBExtensionTypeFloat: return [NSNumber numberWithFloat:[input readFloat]];
|
||||
case PBExtensionTypeFixed64: return [NSNumber numberWithLongLong:[input readFixed64]];
|
||||
case PBExtensionTypeSFixed64: return [NSNumber numberWithLongLong:[input readSFixed64]];
|
||||
case PBExtensionTypeDouble: return [NSNumber numberWithDouble:[input readDouble]];
|
||||
case PBExtensionTypeInt32: return [NSNumber numberWithInt:[input readInt32]];
|
||||
case PBExtensionTypeInt64: return [NSNumber numberWithLongLong:[input readInt64]];
|
||||
case PBExtensionTypeSInt32: return [NSNumber numberWithInt:[input readSInt32]];
|
||||
case PBExtensionTypeSInt64: return [NSNumber numberWithLongLong:[input readSInt64]];
|
||||
case PBExtensionTypeUInt32: return [NSNumber numberWithInt:[input readUInt32]];
|
||||
case PBExtensionTypeUInt64: return [NSNumber numberWithLongLong:[input readUInt64]];
|
||||
case PBExtensionTypeBytes: return [input readData];
|
||||
case PBExtensionTypeString: return [input readString];
|
||||
case PBExtensionTypeEnum: return [NSNumber numberWithInt:[input readEnum]];
|
||||
case PBExtensionTypeGroup:
|
||||
{
|
||||
id<PBMessage_Builder> builder = [messageOrGroupClass builder];
|
||||
[input readGroup:fieldNumber builder:builder extensionRegistry:extensionRegistry];
|
||||
return [builder build];
|
||||
}
|
||||
|
||||
case PBExtensionTypeMessage:
|
||||
{
|
||||
id<PBMessage_Builder> builder = [messageOrGroupClass builder];
|
||||
[input readMessage:builder extensionRegistry:extensionRegistry];
|
||||
return [builder build];
|
||||
}
|
||||
}
|
||||
|
||||
@throw [NSException exceptionWithName:@"InternalError" reason:@"" userInfo:nil];
|
||||
}
|
||||
|
||||
|
||||
- (void) mergeFromCodedInputStream:(PBCodedInputStream*) input
|
||||
unknownFields:(PBUnknownFieldSet_Builder*) unknownFields
|
||||
extensionRegistry:(PBExtensionRegistry*) extensionRegistry
|
||||
builder:(PBExtendableMessage_Builder*) builder
|
||||
tag:(int32_t) tag {
|
||||
if (isPacked) {
|
||||
int32_t length = [input readRawVarint32];
|
||||
int32_t limit = [input pushLimit:length];
|
||||
while ([input bytesUntilLimit] > 0) {
|
||||
id value = [self readSingleValueFromCodedInputStream:input extensionRegistry:extensionRegistry];
|
||||
[builder addExtension:self value:value];
|
||||
}
|
||||
[input popLimit:limit];
|
||||
} else if (isMessageSetWireFormat) {
|
||||
[self mergeMessageSetExtentionFromCodedInputStream:input
|
||||
unknownFields:unknownFields];
|
||||
} else {
|
||||
id value = [self readSingleValueFromCodedInputStream:input extensionRegistry:extensionRegistry];
|
||||
if (isRepeated) {
|
||||
[builder addExtension:self value:value];
|
||||
} else {
|
||||
[builder setExtension:self value:value];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@end
|
|
@ -1,77 +0,0 @@
|
|||
// 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 "GeneratedMessage.h"
|
||||
@protocol PBExtensionField;
|
||||
|
||||
/**
|
||||
* Generated message classes for message types that contain extension ranges
|
||||
* subclass this.
|
||||
*
|
||||
* <p>This class implements type-safe accessors for extensions. They
|
||||
* implement all the same operations that you can do with normal fields --
|
||||
* e.g. "has", "get", and "getCount" -- but for extensions. The extensions
|
||||
* are identified using instances of the class {@link GeneratedExtension};
|
||||
* the protocol compiler generates a static instance of this class for every
|
||||
* extension in its input. Through the magic of generics, all is made
|
||||
* type-safe.
|
||||
*
|
||||
* <p>For example, imagine you have the {@code .proto} file:
|
||||
*
|
||||
* <pre>
|
||||
* option java_class = "MyProto";
|
||||
*
|
||||
* message Foo {
|
||||
* extensions 1000 to max;
|
||||
* }
|
||||
*
|
||||
* extend Foo {
|
||||
* optional int32 bar;
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* <p>Then you might write code like:
|
||||
*
|
||||
* <pre>
|
||||
* MyProto.Foo foo = getFoo();
|
||||
* int i = foo.getExtension(MyProto.bar);
|
||||
* </pre>
|
||||
*
|
||||
* <p>See also {@link ExtendableBuilder}.
|
||||
*/
|
||||
@interface PBExtendableMessage : PBGeneratedMessage {
|
||||
@private
|
||||
NSMutableDictionary* extensionMap;
|
||||
NSMutableDictionary* extensionRegistry;
|
||||
}
|
||||
|
||||
@property (retain) NSMutableDictionary* extensionMap;
|
||||
@property (retain) NSMutableDictionary* extensionRegistry;
|
||||
|
||||
- (BOOL) hasExtension:(id<PBExtensionField>) extension;
|
||||
- (id) getExtension:(id<PBExtensionField>) extension;
|
||||
|
||||
//@protected
|
||||
- (BOOL) extensionsAreInitialized;
|
||||
- (int32_t) extensionsSerializedSize;
|
||||
- (void) writeExtensionsToCodedOutputStream:(PBCodedOutputStream*) output
|
||||
from:(int32_t) startInclusive
|
||||
to:(int32_t) endExclusive;
|
||||
|
||||
|
||||
|
||||
/* @internal */
|
||||
- (void) ensureExtensionIsRegistered:(id<PBExtensionField>) extension;
|
||||
|
||||
@end
|
|
@ -1,106 +0,0 @@
|
|||
// 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 "ExtendableMessage.h"
|
||||
|
||||
#import "ExtensionField.h"
|
||||
|
||||
@implementation PBExtendableMessage
|
||||
|
||||
@synthesize extensionMap;
|
||||
@synthesize extensionRegistry;
|
||||
|
||||
- (void) dealloc {
|
||||
self.extensionMap = nil;
|
||||
self.extensionRegistry = nil;
|
||||
}
|
||||
|
||||
|
||||
- (BOOL) isInitialized:(id) object {
|
||||
if ([object isKindOfClass:[NSArray class]]) {
|
||||
for (id child in object) {
|
||||
if (![self isInitialized:child]) {
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
} else if ([object conformsToProtocol:@protocol(PBMessage)]) {
|
||||
return [object isInitialized];
|
||||
}
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
|
||||
- (BOOL) extensionsAreInitialized {
|
||||
return [self isInitialized:extensionMap.allValues];
|
||||
}
|
||||
|
||||
|
||||
- (id) getExtension:(id<PBExtensionField>) extension {
|
||||
[self ensureExtensionIsRegistered:extension];
|
||||
id value = [extensionMap objectForKey:[NSNumber numberWithInt:[extension fieldNumber]]];
|
||||
if (value != nil) {
|
||||
return value;
|
||||
}
|
||||
|
||||
return [extension defaultValue];
|
||||
}
|
||||
|
||||
|
||||
- (void) ensureExtensionIsRegistered:(id<PBExtensionField>) extension {
|
||||
if ([extension extendedClass] != [self class]) {
|
||||
@throw [NSException exceptionWithName:@"IllegalArgument" reason:@"Trying to use an extension for another type" userInfo:nil];
|
||||
}
|
||||
|
||||
if (extensionRegistry == nil) {
|
||||
self.extensionRegistry = [NSMutableDictionary dictionary];
|
||||
}
|
||||
[extensionRegistry setObject:extension
|
||||
forKey:[NSNumber numberWithInt:[extension fieldNumber]]];
|
||||
}
|
||||
|
||||
|
||||
- (BOOL) hasExtension:(id<PBExtensionField>) extension {
|
||||
return nil != [extensionMap objectForKey:[NSNumber numberWithInt:[extension fieldNumber]]];
|
||||
}
|
||||
|
||||
|
||||
- (void) writeExtensionsToCodedOutputStream:(PBCodedOutputStream*) output
|
||||
from:(int32_t) startInclusive
|
||||
to:(int32_t) endExclusive {
|
||||
// man, i really wish Cocoa had a Sorted/TreeMap
|
||||
NSArray* sortedKeys = [extensionMap.allKeys sortedArrayUsingSelector:@selector(compare:)];
|
||||
for (NSNumber* number in sortedKeys) {
|
||||
int32_t fieldNumber = [number intValue];
|
||||
if (fieldNumber >= startInclusive && fieldNumber < endExclusive) {
|
||||
id<PBExtensionField> extension = [extensionRegistry objectForKey:number];
|
||||
id value = [extensionMap objectForKey:number];
|
||||
[extension writeValue:value includingTagToCodedOutputStream:output];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (int32_t) extensionsSerializedSize {
|
||||
int32_t size = 0;
|
||||
for (NSNumber* number in extensionMap) {
|
||||
id<PBExtensionField> extension = [extensionRegistry objectForKey:number];
|
||||
id value = [extensionMap objectForKey:number];
|
||||
size += [extension computeSerializedSizeIncludingTag:value];
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
@end
|
|
@ -1,75 +0,0 @@
|
|||
// 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 "GeneratedMessage_Builder.h"
|
||||
|
||||
@protocol PBExtensionField;
|
||||
@class PBExtendableMessage_Builder;
|
||||
@class PBExtendableMessage;
|
||||
|
||||
/**
|
||||
* Generated message builders for message types that contain extension ranges
|
||||
* subclass this.
|
||||
*
|
||||
* <p>This class implements type-safe accessors for extensions. They
|
||||
* implement all the same operations that you can do with normal fields --
|
||||
* e.g. "get", "set", and "add" -- but for extensions. The extensions are
|
||||
* identified using instances of the class {@link GeneratedExtension}; the
|
||||
* protocol compiler generates a static instance of this class for every
|
||||
* extension in its input. Through the magic of generics, all is made
|
||||
* type-safe.
|
||||
*
|
||||
* <p>For example, imagine you have the {@code .proto} file:
|
||||
*
|
||||
* <pre>
|
||||
* option java_class = "MyProto";
|
||||
*
|
||||
* message Foo {
|
||||
* extensions 1000 to max;
|
||||
* }
|
||||
*
|
||||
* extend Foo {
|
||||
* optional int32 bar;
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* <p>Then you might write code like:
|
||||
*
|
||||
* <pre>
|
||||
* MyProto.Foo foo =
|
||||
* MyProto.Foo.newBuilder()
|
||||
* .setExtension(MyProto.bar, 123)
|
||||
* .build();
|
||||
* </pre>
|
||||
*
|
||||
* <p>See also {@link ExtendableMessage}.
|
||||
*/
|
||||
@interface PBExtendableMessage_Builder : PBGeneratedMessage_Builder {
|
||||
}
|
||||
|
||||
- (id) getExtension:(id<PBExtensionField>) extension;
|
||||
- (BOOL) hasExtension:(id<PBExtensionField>) extension;
|
||||
- (PBExtendableMessage_Builder*) setExtension:(id<PBExtensionField>) extension
|
||||
value:(id) value;
|
||||
- (PBExtendableMessage_Builder*) addExtension:(id<PBExtensionField>) extension
|
||||
value:(id) value;
|
||||
- (PBExtendableMessage_Builder*) setExtension:(id<PBExtensionField>) extension
|
||||
index:(int32_t) index
|
||||
value:(id) value;
|
||||
- (PBExtendableMessage_Builder*) clearExtension:(id<PBExtensionField>) extension;
|
||||
|
||||
/* @protected */
|
||||
- (void) mergeExtensionFields:(PBExtendableMessage*) other;
|
||||
|
||||
@end
|
|
@ -1,173 +0,0 @@
|
|||
// 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 "ExtendableMessage_Builder.h"
|
||||
|
||||
#import "ExtendableMessage.h"
|
||||
#import "ExtensionField.h"
|
||||
#import "WireFormat.h"
|
||||
#import "ExtensionRegistry.h"
|
||||
|
||||
@implementation PBExtendableMessage_Builder
|
||||
|
||||
- (PBExtendableMessage*) internalGetResult {
|
||||
@throw [NSException exceptionWithName:@"ImproperSubclassing" reason:@"" userInfo:nil];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Called by subclasses to parse an unknown field or an extension.
|
||||
* @return {@code YES} unless the tag is an end-group tag.
|
||||
*/
|
||||
- (BOOL) parseUnknownField:(PBCodedInputStream*) input
|
||||
unknownFields:(PBUnknownFieldSet_Builder*) unknownFields
|
||||
extensionRegistry:(PBExtensionRegistry*) extensionRegistry
|
||||
tag:(int32_t) tag {
|
||||
PBExtendableMessage* message = [self internalGetResult];
|
||||
int32_t wireType = PBWireFormatGetTagWireType(tag);
|
||||
int32_t fieldNumber = PBWireFormatGetTagFieldNumber(tag);
|
||||
|
||||
id<PBExtensionField> extension = [extensionRegistry getExtension:[message class]
|
||||
fieldNumber:fieldNumber];
|
||||
|
||||
if (extension != nil) {
|
||||
if ([extension wireType] == wireType) {
|
||||
[extension mergeFromCodedInputStream:input
|
||||
unknownFields:unknownFields
|
||||
extensionRegistry:extensionRegistry
|
||||
builder:self
|
||||
tag:tag];
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
|
||||
return [super parseUnknownField:input unknownFields:unknownFields extensionRegistry:extensionRegistry tag:tag];
|
||||
}
|
||||
|
||||
|
||||
- (id) getExtension:(id<PBExtensionField>) extension {
|
||||
return [[self internalGetResult] getExtension:extension];
|
||||
}
|
||||
|
||||
|
||||
- (BOOL) hasExtension:(id<PBExtensionField>) extension {
|
||||
return [[self internalGetResult] hasExtension:extension];
|
||||
}
|
||||
|
||||
|
||||
- (PBExtendableMessage_Builder*) setExtension:(id<PBExtensionField>) extension
|
||||
value:(id) value {
|
||||
PBExtendableMessage* message = [self internalGetResult];
|
||||
[message ensureExtensionIsRegistered:extension];
|
||||
|
||||
if ([extension isRepeated]) {
|
||||
@throw [NSException exceptionWithName:@"IllegalArgument" reason:@"Must call addExtension() for repeated types." userInfo:nil];
|
||||
}
|
||||
|
||||
if (message.extensionMap == nil) {
|
||||
message.extensionMap = [NSMutableDictionary dictionary];
|
||||
}
|
||||
[message.extensionMap setObject:value forKey:[NSNumber numberWithInt:[extension fieldNumber]]];
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
- (PBExtendableMessage_Builder*) addExtension:(id<PBExtensionField>) extension
|
||||
value:(id) value {
|
||||
PBExtendableMessage* message = [self internalGetResult];
|
||||
[message ensureExtensionIsRegistered:extension];
|
||||
|
||||
if (![extension isRepeated]) {
|
||||
@throw [NSException exceptionWithName:@"IllegalArgument" reason:@"Must call setExtension() for singular types." userInfo:nil];
|
||||
}
|
||||
|
||||
if (message.extensionMap == nil) {
|
||||
message.extensionMap = [NSMutableDictionary dictionary];
|
||||
}
|
||||
NSNumber* fieldNumber = [NSNumber numberWithInt:[extension fieldNumber]];
|
||||
NSMutableArray* list = [message.extensionMap objectForKey:fieldNumber];
|
||||
if (list == nil) {
|
||||
list = [NSMutableArray array];
|
||||
[message.extensionMap setObject:list forKey:fieldNumber];
|
||||
}
|
||||
|
||||
[list addObject:value];
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
- (PBExtendableMessage_Builder*) setExtension:(id<PBExtensionField>) extension
|
||||
index:(int32_t) index
|
||||
value:(id) value {
|
||||
PBExtendableMessage* message = [self internalGetResult];
|
||||
[message ensureExtensionIsRegistered:extension];
|
||||
|
||||
if (![extension isRepeated]) {
|
||||
@throw [NSException exceptionWithName:@"IllegalArgument" reason:@"Must call setExtension() for singular types." userInfo:nil];
|
||||
}
|
||||
|
||||
if (message.extensionMap == nil) {
|
||||
message.extensionMap = [NSMutableDictionary dictionary];
|
||||
}
|
||||
|
||||
NSNumber* fieldNumber = [NSNumber numberWithInt:[extension fieldNumber]];
|
||||
NSMutableArray* list = [message.extensionMap objectForKey:fieldNumber];
|
||||
|
||||
[list replaceObjectAtIndex:(NSUInteger)index withObject:value];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
- (PBExtendableMessage_Builder*) clearExtension:(id<PBExtensionField>) extension {
|
||||
PBExtendableMessage* message = [self internalGetResult];
|
||||
[message ensureExtensionIsRegistered:extension];
|
||||
[message.extensionMap removeObjectForKey:[NSNumber numberWithInt:[extension fieldNumber]]];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
- (void) mergeExtensionFields:(PBExtendableMessage*) other {
|
||||
PBExtendableMessage* thisMessage = [self internalGetResult];
|
||||
if ([thisMessage class] != [other class]) {
|
||||
@throw [NSException exceptionWithName:@"IllegalArgument" reason:@"Cannot merge extensions from a different type" userInfo:nil];
|
||||
}
|
||||
|
||||
if (other.extensionMap.count > 0) {
|
||||
if (thisMessage.extensionMap == nil) {
|
||||
thisMessage.extensionMap = [NSMutableDictionary dictionary];
|
||||
}
|
||||
|
||||
NSDictionary* registry = other.extensionRegistry;
|
||||
for (NSNumber* fieldNumber in other.extensionMap) {
|
||||
id<PBExtensionField> thisField = [registry objectForKey:fieldNumber];
|
||||
id value = [other.extensionMap objectForKey:fieldNumber];
|
||||
|
||||
if ([thisField isRepeated]) {
|
||||
NSMutableArray* list = [thisMessage.extensionMap objectForKey:fieldNumber];
|
||||
if (list == nil) {
|
||||
list = [NSMutableArray array];
|
||||
[thisMessage.extensionMap setObject:list forKey:fieldNumber];
|
||||
}
|
||||
|
||||
[list addObjectsFromArray:value];
|
||||
} else {
|
||||
[thisMessage.extensionMap setObject:value forKey:fieldNumber];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
|
@ -1,36 +0,0 @@
|
|||
// 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 "WireFormat.h"
|
||||
@class PBCodedInputStream;
|
||||
@class PBUnknownFieldSet_Builder;
|
||||
@class PBExtendableMessage_Builder;
|
||||
@class PBCodedOutputStream;
|
||||
@class PBExtensionRegistry;
|
||||
|
||||
@protocol PBExtensionField
|
||||
- (int32_t) fieldNumber;
|
||||
- (PBWireFormat) wireType;
|
||||
- (BOOL) isRepeated;
|
||||
- (Class) extendedClass;
|
||||
- (id) defaultValue;
|
||||
|
||||
- (void) mergeFromCodedInputStream:(PBCodedInputStream*) input
|
||||
unknownFields:(PBUnknownFieldSet_Builder*) unknownFields
|
||||
extensionRegistry:(PBExtensionRegistry*) extensionRegistry
|
||||
builder:(PBExtendableMessage_Builder*) builder
|
||||
tag:(int32_t) tag;
|
||||
- (void) writeValue:(id) value includingTagToCodedOutputStream:(PBCodedOutputStream*) output;
|
||||
- (int32_t) computeSerializedSizeIncludingTag:(id) value;
|
||||
@end
|
|
@ -1,83 +0,0 @@
|
|||
// 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.
|
||||
|
||||
/**
|
||||
* A table of known extensions, searchable by name or field number. When
|
||||
* parsing a protocol message that might have extensions, you must provide
|
||||
* an {@code ExtensionRegistry} in which you have registered any extensions
|
||||
* that you want to be able to parse. Otherwise, those extensions will just
|
||||
* be treated like unknown fields.
|
||||
*
|
||||
* <p>For example, if you had the {@code .proto} file:
|
||||
*
|
||||
* <pre>
|
||||
* option java_class = "MyProto";
|
||||
*
|
||||
* message Foo {
|
||||
* extensions 1000 to max;
|
||||
* }
|
||||
*
|
||||
* extend Foo {
|
||||
* optional int32 bar;
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* Then you might write code like:
|
||||
*
|
||||
* <pre>
|
||||
* ExtensionRegistry registry = ExtensionRegistry.newInstance();
|
||||
* registry.add(MyProto.bar);
|
||||
* MyProto.Foo message = MyProto.Foo.parseFrom(input, registry);
|
||||
* </pre>
|
||||
*
|
||||
* <p>Background:
|
||||
*
|
||||
* <p>You might wonder why this is necessary. Two alternatives might come to
|
||||
* mind. First, you might imagine a system where generated extensions are
|
||||
* automatically registered when their containing classes are loaded. This
|
||||
* is a popular technique, but is bad design; among other things, it creates a
|
||||
* situation where behavior can change depending on what classes happen to be
|
||||
* loaded. It also introduces a security vulnerability, because an
|
||||
* unprivileged class could cause its code to be called unexpectedly from a
|
||||
* privileged class by registering itself as an extension of the right type.
|
||||
*
|
||||
* <p>Another option you might consider is lazy parsing: do not parse an
|
||||
* extension until it is first requested, at which point the caller must
|
||||
* provide a type to use. This introduces a different set of problems. First,
|
||||
* it would require a mutex lock any time an extension was accessed, which
|
||||
* would be slow. Second, corrupt data would not be detected until first
|
||||
* access, at which point it would be much harder to deal with it. Third, it
|
||||
* could violate the expectation that message objects are immutable, since the
|
||||
* type provided could be any arbitrary message class. An unpriviledged user
|
||||
* could take advantage of this to inject a mutable object into a message
|
||||
* belonging to priviledged code and create mischief.
|
||||
*
|
||||
* @author Cyrus Najmabadi
|
||||
*/
|
||||
|
||||
@protocol PBExtensionField;
|
||||
|
||||
@interface PBExtensionRegistry : NSObject {
|
||||
@protected
|
||||
NSDictionary* classMap;
|
||||
}
|
||||
|
||||
+ (PBExtensionRegistry*) emptyRegistry;
|
||||
- (id<PBExtensionField>) getExtension:(Class) clazz fieldNumber:(NSInteger) fieldNumber;
|
||||
|
||||
/* @protected */
|
||||
- (id) initWithClassMap:(NSDictionary*) classMap;
|
||||
- (id) keyForClass:(Class) clazz;
|
||||
|
||||
@end
|
|
@ -1,62 +0,0 @@
|
|||
// 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 "ExtensionRegistry.h"
|
||||
|
||||
@interface PBExtensionRegistry()
|
||||
@property (retain) NSDictionary* classMap;
|
||||
@end
|
||||
|
||||
@implementation PBExtensionRegistry
|
||||
|
||||
@synthesize classMap;
|
||||
|
||||
- (void) dealloc {
|
||||
self.classMap = nil;
|
||||
}
|
||||
|
||||
static PBExtensionRegistry* emptyRegistry = nil;
|
||||
|
||||
+ (void) initialize {
|
||||
if (self == [PBExtensionRegistry class]) {
|
||||
emptyRegistry = [[PBExtensionRegistry alloc] initWithClassMap:[NSDictionary dictionary]];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (id) initWithClassMap:(NSDictionary*) map_{
|
||||
if ((self = [super init])) {
|
||||
self.classMap = map_;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
- (id) keyForClass:(Class) clazz {
|
||||
return NSStringFromClass(clazz);
|
||||
}
|
||||
|
||||
|
||||
+ (PBExtensionRegistry*) emptyRegistry {
|
||||
return emptyRegistry;
|
||||
}
|
||||
|
||||
|
||||
- (id<PBExtensionField>) getExtension:(Class) clazz fieldNumber:(NSInteger) fieldNumber {
|
||||
NSDictionary* extensionMap = [classMap objectForKey:[self keyForClass:clazz]];
|
||||
return [extensionMap objectForKey:[NSNumber numberWithInteger:fieldNumber]];
|
||||
}
|
||||
|
||||
@end
|
|
@ -1,42 +0,0 @@
|
|||
// 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.
|
||||
|
||||
@class PBCodedOutputStream;
|
||||
|
||||
@interface PBField : NSObject {
|
||||
@protected
|
||||
NSMutableArray* mutableVarintList;
|
||||
NSMutableArray* mutableFixed32List;
|
||||
NSMutableArray* mutableFixed64List;
|
||||
NSMutableArray* mutableLengthDelimitedList;
|
||||
NSMutableArray* mutableGroupList;
|
||||
}
|
||||
|
||||
- (NSArray*) varintList;
|
||||
- (NSArray*) fixed32List;
|
||||
- (NSArray*) fixed64List;
|
||||
- (NSArray*) lengthDelimitedList;
|
||||
- (NSArray*) groupList;
|
||||
|
||||
+ (PBField*) defaultInstance;
|
||||
|
||||
- (void) writeTo:(int32_t) fieldNumber
|
||||
output:(PBCodedOutputStream*) output;
|
||||
|
||||
- (int32_t) getSerializedSize:(int32_t) fieldNumber;
|
||||
- (void) writeAsMessageSetExtensionTo:(int32_t) fieldNumber
|
||||
output:(PBCodedOutputStream*) output;
|
||||
- (int32_t) getSerializedSizeAsMessageSetExtension:(int32_t) fieldNumber;
|
||||
|
||||
@end
|
|
@ -1,143 +0,0 @@
|
|||
// 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 "Field.h"
|
||||
|
||||
#import "CodedOutputStream.h"
|
||||
#import "MutableField.h"
|
||||
|
||||
@interface PBField ()
|
||||
@property (retain) NSMutableArray* mutableVarintList;
|
||||
@property (retain) NSMutableArray* mutableFixed32List;
|
||||
@property (retain) NSMutableArray* mutableFixed64List;
|
||||
@property (retain) NSMutableArray* mutableLengthDelimitedList;
|
||||
@property (retain) NSMutableArray* mutableGroupList;
|
||||
@end
|
||||
|
||||
@implementation PBField
|
||||
|
||||
static PBField* defaultInstance = nil;
|
||||
|
||||
+ (void) initialize {
|
||||
if (self == [PBField class]) {
|
||||
defaultInstance = [[PBField alloc] init];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@synthesize mutableVarintList;
|
||||
@synthesize mutableFixed32List;
|
||||
@synthesize mutableFixed64List;
|
||||
@synthesize mutableLengthDelimitedList;
|
||||
@synthesize mutableGroupList;
|
||||
|
||||
|
||||
- (void) dealloc {
|
||||
self.mutableVarintList = nil;
|
||||
self.mutableFixed32List = nil;
|
||||
self.mutableFixed64List = nil;
|
||||
self.mutableLengthDelimitedList = nil;
|
||||
self.mutableGroupList = nil;
|
||||
}
|
||||
|
||||
|
||||
+ (PBField*) defaultInstance {
|
||||
return defaultInstance;
|
||||
}
|
||||
|
||||
|
||||
- (NSArray*) varintList {
|
||||
return mutableVarintList;
|
||||
}
|
||||
|
||||
|
||||
- (NSArray*) fixed32List {
|
||||
return mutableFixed32List;
|
||||
}
|
||||
|
||||
|
||||
- (NSArray*) fixed64List {
|
||||
return mutableFixed64List;
|
||||
}
|
||||
|
||||
|
||||
- (NSArray*) lengthDelimitedList {
|
||||
return mutableLengthDelimitedList;
|
||||
}
|
||||
|
||||
|
||||
- (NSArray*) groupList {
|
||||
return mutableGroupList;
|
||||
}
|
||||
|
||||
|
||||
- (void) writeTo:(int32_t) fieldNumber
|
||||
output:(PBCodedOutputStream*) output {
|
||||
for (NSNumber* value in self.varintList) {
|
||||
[output writeUInt64:fieldNumber value:value.longLongValue];
|
||||
}
|
||||
for (NSNumber* value in self.fixed32List) {
|
||||
[output writeFixed32:fieldNumber value:value.intValue];
|
||||
}
|
||||
for (NSNumber* value in self.fixed64List) {
|
||||
[output writeFixed64:fieldNumber value:value.longLongValue];
|
||||
}
|
||||
for (NSData* value in self.lengthDelimitedList) {
|
||||
[output writeData:fieldNumber value:value];
|
||||
}
|
||||
for (PBUnknownFieldSet* value in self.groupList) {
|
||||
[output writeUnknownGroup:fieldNumber value:value];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (int32_t) getSerializedSize:(int32_t) fieldNumber {
|
||||
int32_t result = 0;
|
||||
for (NSNumber* value in self.varintList) {
|
||||
result += computeUInt64Size(fieldNumber, value.longLongValue);
|
||||
}
|
||||
for (NSNumber* value in self.fixed32List) {
|
||||
result += computeFixed32Size(fieldNumber, value.intValue);
|
||||
}
|
||||
for (NSNumber* value in self.fixed64List) {
|
||||
result += computeFixed64Size(fieldNumber, value.longLongValue);
|
||||
}
|
||||
for (NSData* value in self.lengthDelimitedList) {
|
||||
result += computeDataSize(fieldNumber, value);
|
||||
}
|
||||
for (PBUnknownFieldSet* value in self.groupList) {
|
||||
result += computeUnknownGroupSize(fieldNumber, value);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
- (void) writeAsMessageSetExtensionTo:(int32_t) fieldNumber
|
||||
output:(PBCodedOutputStream*) output {
|
||||
for (NSData* value in self.lengthDelimitedList) {
|
||||
[output writeRawMessageSetExtension:fieldNumber value:value];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (int32_t) getSerializedSizeAsMessageSetExtension:(int32_t) fieldNumber {
|
||||
int32_t result = 0;
|
||||
for (NSData* value in self.lengthDelimitedList) {
|
||||
result += computeRawMessageSetExtensionSize(fieldNumber, value);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@end
|
|
@ -1,32 +0,0 @@
|
|||
// 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.
|
||||
|
||||
@protocol PBMessage;
|
||||
@protocol PBMessage_Builder;
|
||||
@protocol PBExtensionField;
|
||||
|
||||
@class PBAbstractMessage;
|
||||
@class PBCodedInputStream;
|
||||
@class PBCodedOutputStream;
|
||||
@class PBConcreteExtensionField;
|
||||
@class PBExtendableMessage_Builder;
|
||||
@class PBExtendableMessage;
|
||||
@class PBExtensionRegistry;
|
||||
@class PBField;
|
||||
@class PBGeneratedMessage;
|
||||
@class PBGeneratedMessage_Builder;
|
||||
@class PBMutableExtensionRegistry;
|
||||
@class PBMutableField;
|
||||
@class PBUnknownFieldSet;
|
||||
@class PBUnknownFieldSet_Builder;
|
|
@ -1,33 +0,0 @@
|
|||
// 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 "AbstractMessage.h"
|
||||
|
||||
/**
|
||||
* All generated protocol message classes extend this class. This class
|
||||
* implements most of the Message and Builder interfaces using Java reflection.
|
||||
* Users can ignore this class and pretend that generated messages implement
|
||||
* the Message interface directly.
|
||||
*
|
||||
* @author Cyrus Najmabadi
|
||||
*/
|
||||
@interface PBGeneratedMessage : PBAbstractMessage {
|
||||
@private
|
||||
PBUnknownFieldSet* unknownFields;
|
||||
|
||||
@protected
|
||||
int32_t memoizedSerializedSize;
|
||||
}
|
||||
|
||||
@end
|
|
@ -1,42 +0,0 @@
|
|||
// 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 "GeneratedMessage.h"
|
||||
|
||||
#import "UnknownFieldSet.h"
|
||||
|
||||
@interface PBGeneratedMessage ()
|
||||
@property (retain) PBUnknownFieldSet* unknownFields;
|
||||
@end
|
||||
|
||||
|
||||
@implementation PBGeneratedMessage
|
||||
|
||||
@synthesize unknownFields;
|
||||
|
||||
- (void) dealloc {
|
||||
self.unknownFields = nil;
|
||||
}
|
||||
|
||||
|
||||
- (id) init {
|
||||
if ((self = [super init])) {
|
||||
self.unknownFields = [PBUnknownFieldSet defaultInstance];
|
||||
memoizedSerializedSize = -1;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
|
@ -1,30 +0,0 @@
|
|||
// 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 "AbstractMessage_Builder.h"
|
||||
|
||||
@class PBUnknownFieldSet_Builder;
|
||||
|
||||
@interface PBGeneratedMessage_Builder : PBAbstractMessage_Builder {
|
||||
}
|
||||
|
||||
/* @protected */
|
||||
- (BOOL) parseUnknownField:(PBCodedInputStream*) input
|
||||
unknownFields:(PBUnknownFieldSet_Builder*) unknownFields
|
||||
extensionRegistry:(PBExtensionRegistry*) extensionRegistry
|
||||
tag:(int32_t) tag;
|
||||
|
||||
- (void) checkInitialized;
|
||||
|
||||
@end
|
|
@ -1,92 +0,0 @@
|
|||
// 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 "GeneratedMessage_Builder.h"
|
||||
|
||||
#import "GeneratedMessage.h"
|
||||
#import "Message.h"
|
||||
#import "Message_Builder.h"
|
||||
#import "UnknownFieldSet.h"
|
||||
#import "UnknownFieldSet_Builder.h"
|
||||
|
||||
|
||||
@interface PBGeneratedMessage ()
|
||||
@property (retain) PBUnknownFieldSet* unknownFields;
|
||||
@end
|
||||
|
||||
|
||||
@implementation PBGeneratedMessage_Builder
|
||||
|
||||
/**
|
||||
* Get the message being built. We don't just pass this to the
|
||||
* constructor because it becomes null when build() is called.
|
||||
*/
|
||||
- (PBGeneratedMessage*) internalGetResult {
|
||||
@throw [NSException exceptionWithName:@"ImproperSubclassing" reason:@"" userInfo:nil];
|
||||
}
|
||||
|
||||
|
||||
- (void) checkInitialized {
|
||||
PBGeneratedMessage* result = self.internalGetResult;
|
||||
if (result != nil && !result.isInitialized) {
|
||||
@throw [NSException exceptionWithName:@"UninitializedMessage" reason:@"" userInfo:nil];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (PBUnknownFieldSet*) unknownFields {
|
||||
return self.internalGetResult.unknownFields;
|
||||
}
|
||||
|
||||
|
||||
- (id<PBMessage_Builder>) setUnknownFields:(PBUnknownFieldSet*) unknownFields {
|
||||
self.internalGetResult.unknownFields = unknownFields;
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
- (id<PBMessage_Builder>) mergeUnknownFields:(PBUnknownFieldSet*) unknownFields {
|
||||
PBGeneratedMessage* result = self.internalGetResult;
|
||||
result.unknownFields =
|
||||
[[[PBUnknownFieldSet builderWithUnknownFields:result.unknownFields]
|
||||
mergeUnknownFields:unknownFields] build];
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
- (BOOL) isInitialized {
|
||||
return self.internalGetResult.isInitialized;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Called by subclasses to parse an unknown field.
|
||||
* @return {@code YES} unless the tag is an end-group tag.
|
||||
*/
|
||||
- (BOOL) parseUnknownField:(PBCodedInputStream*) input
|
||||
unknownFields:(PBUnknownFieldSet_Builder*) unknownFields
|
||||
extensionRegistry:(PBExtensionRegistry*) extensionRegistry
|
||||
tag:(int32_t) tag {
|
||||
return [unknownFields mergeFieldFrom:tag input:input];
|
||||
}
|
||||
|
||||
|
||||
- (void) checkInitializedParsed {
|
||||
PBGeneratedMessage* result = self.internalGetResult;
|
||||
if (result != nil && !result.isInitialized) {
|
||||
@throw [NSException exceptionWithName:@"InvalidProtocolBuffer" reason:@"" userInfo:nil];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
|
@ -1,70 +0,0 @@
|
|||
// 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.
|
||||
|
||||
@class PBUnknownFieldSet;
|
||||
@class PBCodedOutputStream;
|
||||
@protocol PBMessage_Builder;
|
||||
|
||||
/**
|
||||
* Abstract interface implemented by Protocol Message objects.
|
||||
*
|
||||
* @author Cyrus Najmabadi
|
||||
*/
|
||||
@protocol PBMessage<NSObject>
|
||||
/**
|
||||
* Get an instance of the type with all fields set to their default values.
|
||||
* This may or may not be a singleton. This differs from the
|
||||
* {@code getDefaultInstance()} method of generated message classes in that
|
||||
* this method is an abstract method of the {@code Message} interface
|
||||
* whereas {@code getDefaultInstance()} is a static method of a specific
|
||||
* class. They return the same thing.
|
||||
*/
|
||||
- (id<PBMessage>) defaultInstance;
|
||||
|
||||
/**
|
||||
* Get the {@code UnknownFieldSet}
|
||||
*/
|
||||
- (PBUnknownFieldSet*) unknownFields;
|
||||
|
||||
/**
|
||||
* Get the number of bytes required to encode this message. The result
|
||||
* is only computed on the first call and memoized after that.
|
||||
*/
|
||||
- (int32_t) serializedSize;
|
||||
|
||||
/**
|
||||
* Returns true if all required fields in the message and all embedded
|
||||
* messages are set, false otherwise.
|
||||
*/
|
||||
- (BOOL) isInitialized;
|
||||
|
||||
/**
|
||||
* Serializes the message and writes it to {@code output}. This does not
|
||||
* flush or close the stream.
|
||||
*/
|
||||
- (void) writeToCodedOutputStream:(PBCodedOutputStream*) output;
|
||||
- (void) writeToOutputStream:(NSOutputStream*) output;
|
||||
|
||||
/**
|
||||
* Serializes the message to a {@code ByteString} and returns it. This is
|
||||
* just a trivial wrapper around
|
||||
* {@link #writeTo(CodedOutputStream)}.
|
||||
*/
|
||||
- (NSData*) data;
|
||||
|
||||
/**
|
||||
* Constructs a new builder for a message of the same type as this message.
|
||||
*/
|
||||
- (id<PBMessage_Builder>) builder;
|
||||
@end
|
|
@ -1,134 +0,0 @@
|
|||
// 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.
|
||||
|
||||
@protocol PBMessage;
|
||||
@protocol PBMessage_Builder;
|
||||
@class PBUnknownFieldSet;
|
||||
@class PBCodedInputStream;
|
||||
@class PBExtensionRegistry;
|
||||
|
||||
/**
|
||||
* Abstract interface implemented by Protocol Message builders.
|
||||
*/
|
||||
@protocol PBMessage_Builder<NSObject>
|
||||
/** Resets all fields to their default values. */
|
||||
- (id<PBMessage_Builder>) clear;
|
||||
|
||||
/**
|
||||
* Construct the final message. Once this is called, the Builder is no
|
||||
* longer valid, and calling any other method may throw a
|
||||
* NullPointerException. If you need to continue working with the builder
|
||||
* after calling {@code build()}, {@code clone()} it first.
|
||||
* @throws UninitializedMessageException The message is missing one or more
|
||||
* required fields (i.e. {@link #isInitialized()} returns false).
|
||||
* Use {@link #buildPartial()} to bypass this check.
|
||||
*/
|
||||
- (id<PBMessage>) build;
|
||||
|
||||
/**
|
||||
* Like {@link #build()}, but does not throw an exception if the message
|
||||
* is missing required fields. Instead, a partial message is returned.
|
||||
*/
|
||||
- (id<PBMessage>) buildPartial;
|
||||
- (id<PBMessage_Builder>) clone;
|
||||
|
||||
/**
|
||||
* Returns true if all required fields in the message and all embedded
|
||||
* messages are set, false otherwise.
|
||||
*/
|
||||
- (BOOL) isInitialized;
|
||||
|
||||
/**
|
||||
* Get the message's type's default instance.
|
||||
* See {@link Message#getDefaultInstanceForType()}.
|
||||
*/
|
||||
- (id<PBMessage>) defaultInstance;
|
||||
|
||||
- (PBUnknownFieldSet*) unknownFields;
|
||||
- (id<PBMessage_Builder>) setUnknownFields:(PBUnknownFieldSet*) unknownFields;
|
||||
|
||||
/**
|
||||
* Merge some unknown fields into the {@link UnknownFieldSet} for this
|
||||
* message.
|
||||
*/
|
||||
- (id<PBMessage_Builder>) mergeUnknownFields:(PBUnknownFieldSet*) unknownFields;
|
||||
|
||||
/**
|
||||
* Parses a message of this type from the input and merges it with this
|
||||
* message, as if using {@link Builder#mergeFrom(Message)}.
|
||||
*
|
||||
* <p>Warning: This does not verify that all required fields are present in
|
||||
* the input message. If you call {@link #build()} without setting all
|
||||
* required fields, it will throw an {@link UninitializedMessageException},
|
||||
* which is a {@code RuntimeException} and thus might not be caught. There
|
||||
* are a few good ways to deal with this:
|
||||
* <ul>
|
||||
* <li>Call {@link #isInitialized()} to verify that all required fields
|
||||
* are set before building.
|
||||
* <li>Parse the message separately using one of the static
|
||||
* {@code parseFrom} methods, then use {@link #mergeFrom(Message)}
|
||||
* to merge it with this one. {@code parseFrom} will throw an
|
||||
* {@link InvalidProtocolBufferException} (an {@code IOException})
|
||||
* if some required fields are missing.
|
||||
* <li>Use {@code buildPartial()} to build, which ignores missing
|
||||
* required fields.
|
||||
* </ul>
|
||||
*
|
||||
* <p>Note: The caller should call
|
||||
* {@link CodedInputStream#checkLastTagWas(int)} after calling this to
|
||||
* verify that the last tag seen was the appropriate end-group tag,
|
||||
* or zero for EOF.
|
||||
*/
|
||||
- (id<PBMessage_Builder>) mergeFromCodedInputStream:(PBCodedInputStream*) input;
|
||||
|
||||
/**
|
||||
* Like {@link Builder#mergeFrom(CodedInputStream)}, but also
|
||||
* parses extensions. The extensions that you want to be able to parse
|
||||
* must be registered in {@code extensionRegistry}. Extensions not in
|
||||
* the registry will be treated as unknown fields.
|
||||
*/
|
||||
- (id<PBMessage_Builder>) mergeFromCodedInputStream:(PBCodedInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
|
||||
|
||||
/**
|
||||
* Parse {@code data} as a message of this type and merge it with the
|
||||
* message being built. This is just a small wrapper around
|
||||
* {@link #mergeFrom(CodedInputStream)}.
|
||||
*/
|
||||
- (id<PBMessage_Builder>) mergeFromData:(NSData*) data;
|
||||
|
||||
/**
|
||||
* Parse {@code data} as a message of this type and merge it with the
|
||||
* message being built. This is just a small wrapper around
|
||||
* {@link #mergeFrom(CodedInputStream,ExtensionRegistry)}.
|
||||
*/
|
||||
- (id<PBMessage_Builder>) mergeFromData:(NSData*) data extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
|
||||
|
||||
/**
|
||||
* Parse a message of this type from {@code input} and merge it with the
|
||||
* message being built. This is just a small wrapper around
|
||||
* {@link #mergeFrom(CodedInputStream)}. Note that this method always
|
||||
* reads the <i>entire</i> input (unless it throws an exception). If you
|
||||
* want it to stop earlier, you will need to wrap your input in some
|
||||
* wrapper stream that limits reading. Despite usually reading the entire
|
||||
* input, this does not close the stream.
|
||||
*/
|
||||
- (id<PBMessage_Builder>) mergeFromInputStream:(NSInputStream*) input;
|
||||
|
||||
/**
|
||||
* Parse a message of this type from {@code input} and merge it with the
|
||||
* message being built. This is just a small wrapper around
|
||||
* {@link #mergeFrom(CodedInputStream,ExtensionRegistry)}.
|
||||
*/
|
||||
- (id<PBMessage_Builder>) mergeFromInputStream:(NSInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
|
||||
@end
|
|
@ -1,26 +0,0 @@
|
|||
// 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 "ExtensionRegistry.h"
|
||||
|
||||
@interface PBMutableExtensionRegistry : PBExtensionRegistry {
|
||||
@private
|
||||
NSMutableDictionary* mutableClassMap;
|
||||
}
|
||||
|
||||
+ (PBMutableExtensionRegistry*) registry;
|
||||
|
||||
- (void) addExtension:(id<PBExtensionField>) extension;
|
||||
|
||||
@end
|
|
@ -1,65 +0,0 @@
|
|||
// 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 "MutableExtensionRegistry.h"
|
||||
|
||||
#import "ExtensionField.h"
|
||||
|
||||
@interface PBMutableExtensionRegistry()
|
||||
@property (retain) NSMutableDictionary* mutableClassMap;
|
||||
@end
|
||||
|
||||
@implementation PBMutableExtensionRegistry
|
||||
|
||||
@synthesize mutableClassMap;
|
||||
|
||||
- (void) dealloc {
|
||||
self.mutableClassMap = nil;
|
||||
}
|
||||
|
||||
|
||||
- (id) initWithClassMap:(NSMutableDictionary*) mutableClassMap_ {
|
||||
if ((self = [super initWithClassMap:mutableClassMap_])) {
|
||||
self.mutableClassMap = mutableClassMap_;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
+ (PBMutableExtensionRegistry*) registry {
|
||||
return [[PBMutableExtensionRegistry alloc] initWithClassMap:[NSMutableDictionary dictionary]];
|
||||
}
|
||||
|
||||
|
||||
- (void) addExtension:(id<PBExtensionField>) extension {
|
||||
if (extension == nil) {
|
||||
return;
|
||||
}
|
||||
|
||||
Class extendedClass = [extension extendedClass];
|
||||
id key = [self keyForClass:extendedClass];
|
||||
|
||||
NSMutableDictionary* extensionMap = [classMap objectForKey:key];
|
||||
if (extensionMap == nil) {
|
||||
extensionMap = [NSMutableDictionary dictionary];
|
||||
[mutableClassMap setObject:extensionMap forKey:key];
|
||||
}
|
||||
|
||||
[extensionMap setObject:extension
|
||||
forKey:[NSNumber numberWithInteger:[extension fieldNumber]]];
|
||||
}
|
||||
|
||||
|
||||
@end
|
|
@ -1,33 +0,0 @@
|
|||
// 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 "Field.h"
|
||||
|
||||
@class PBUnknownFieldSet;
|
||||
|
||||
@interface PBMutableField : PBField {
|
||||
}
|
||||
|
||||
+ (PBMutableField*) field;
|
||||
|
||||
- (PBMutableField*) mergeFromField:(PBField*) other;
|
||||
|
||||
- (PBMutableField*) clear;
|
||||
- (PBMutableField*) addVarint:(int64_t) value;
|
||||
- (PBMutableField*) addFixed32:(int32_t) value;
|
||||
- (PBMutableField*) addFixed64:(int64_t) value;
|
||||
- (PBMutableField*) addLengthDelimited:(NSData*) value;
|
||||
- (PBMutableField*) addGroup:(PBUnknownFieldSet*) value;
|
||||
|
||||
@end
|
|
@ -1,138 +0,0 @@
|
|||
// 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 "MutableField.h"
|
||||
|
||||
#import "Field.h"
|
||||
|
||||
@interface PBField ()
|
||||
@property (retain) NSMutableArray* mutableVarintList;
|
||||
@property (retain) NSMutableArray* mutableFixed32List;
|
||||
@property (retain) NSMutableArray* mutableFixed64List;
|
||||
@property (retain) NSMutableArray* mutableLengthDelimitedList;
|
||||
@property (retain) NSMutableArray* mutableGroupList;
|
||||
@end
|
||||
|
||||
|
||||
@implementation PBMutableField
|
||||
|
||||
|
||||
+ (PBMutableField*) field {
|
||||
return [[PBMutableField alloc] init];
|
||||
}
|
||||
|
||||
|
||||
- (id) init {
|
||||
if ((self = [super init])) {
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
- (PBMutableField*) clear {
|
||||
self.mutableVarintList = nil;
|
||||
self.mutableFixed32List = nil;
|
||||
self.mutableFixed64List = nil;
|
||||
self.mutableLengthDelimitedList = nil;
|
||||
self.mutableGroupList = nil;
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
- (PBMutableField*) mergeFromField:(PBField*) other {
|
||||
if (other.varintList.count > 0) {
|
||||
if (mutableVarintList == nil) {
|
||||
self.mutableVarintList = [NSMutableArray array];
|
||||
}
|
||||
[mutableVarintList addObjectsFromArray:other.varintList];
|
||||
}
|
||||
|
||||
if (other.fixed32List.count > 0) {
|
||||
if (mutableFixed32List == nil) {
|
||||
self.mutableFixed32List = [NSMutableArray array];
|
||||
}
|
||||
[mutableFixed32List addObjectsFromArray:other.fixed32List];
|
||||
}
|
||||
|
||||
if (other.fixed64List.count > 0) {
|
||||
if (mutableFixed64List == nil) {
|
||||
self.mutableFixed64List = [NSMutableArray array];
|
||||
}
|
||||
[mutableFixed64List addObjectsFromArray:other.fixed64List];
|
||||
}
|
||||
|
||||
if (other.lengthDelimitedList.count > 0) {
|
||||
if (mutableLengthDelimitedList == nil) {
|
||||
self.mutableLengthDelimitedList = [NSMutableArray array];
|
||||
}
|
||||
[mutableLengthDelimitedList addObjectsFromArray:other.lengthDelimitedList];
|
||||
}
|
||||
|
||||
if (other.groupList.count > 0) {
|
||||
if (mutableGroupList == nil) {
|
||||
self.mutableGroupList = [NSMutableArray array];
|
||||
}
|
||||
[mutableGroupList addObjectsFromArray:other.groupList];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
- (PBMutableField*) addVarint:(int64_t) value {
|
||||
if (mutableVarintList == nil) {
|
||||
self.mutableVarintList = [NSMutableArray array];
|
||||
}
|
||||
[mutableVarintList addObject:[NSNumber numberWithLongLong:value]];
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
- (PBMutableField*) addFixed32:(int32_t) value {
|
||||
if (mutableFixed32List == nil) {
|
||||
self.mutableFixed32List = [NSMutableArray array];
|
||||
}
|
||||
[mutableFixed32List addObject:[NSNumber numberWithInt:value]];
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
- (PBMutableField*) addFixed64:(int64_t) value {
|
||||
if (mutableFixed64List == nil) {
|
||||
self.mutableFixed64List = [NSMutableArray array];
|
||||
}
|
||||
[mutableFixed64List addObject:[NSNumber numberWithLongLong:value]];
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
- (PBMutableField*) addLengthDelimited:(NSData*) value {
|
||||
if (mutableLengthDelimitedList == nil) {
|
||||
self.mutableLengthDelimitedList = [NSMutableArray array];
|
||||
}
|
||||
[mutableLengthDelimitedList addObject:value];
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
- (PBMutableField*) addGroup:(PBUnknownFieldSet*) value {
|
||||
if (mutableGroupList == nil) {
|
||||
self.mutableGroupList = [NSMutableArray array];
|
||||
}
|
||||
[mutableGroupList addObject:value];
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
|
@ -1,36 +0,0 @@
|
|||
// 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 "Bootstrap.h"
|
||||
|
||||
#import "AbstractMessage.h"
|
||||
#import "AbstractMessage_Builder.h"
|
||||
#import "CodedInputStream.h"
|
||||
#import "CodedOutputStream.h"
|
||||
#import "ConcreteExtensionField.h"
|
||||
#import "ExtendableMessage.h"
|
||||
#import "ExtendableMessage_Builder.h"
|
||||
#import "ExtensionField.h"
|
||||
#import "ExtensionRegistry.h"
|
||||
#import "Field.h"
|
||||
#import "GeneratedMessage.h"
|
||||
#import "GeneratedMessage_Builder.h"
|
||||
#import "Message.h"
|
||||
#import "Message_Builder.h"
|
||||
#import "MutableExtensionRegistry.h"
|
||||
#import "MutableField.h"
|
||||
#import "UnknownFieldSet.h"
|
||||
#import "UnknownFieldSet_Builder.h"
|
||||
#import "Utilities.h"
|
||||
#import "WireFormat.h"
|
|
@ -1,26 +0,0 @@
|
|||
// 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.
|
||||
|
||||
@interface PBTextFormat : NSObject {
|
||||
|
||||
}
|
||||
|
||||
+ (int32_t) parseInt32:(NSString*) text;
|
||||
+ (int32_t) parseUInt32:(NSString*) text;
|
||||
+ (int64_t) parseInt64:(NSString*) text;
|
||||
+ (int64_t) parseUInt64:(NSString*) text;
|
||||
|
||||
+ (NSData*) unescapeBytes:(NSString*) input;
|
||||
|
||||
@end
|
|
@ -1,238 +0,0 @@
|
|||
// 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 "TextFormat.h"
|
||||
|
||||
#import "Utilities.h"
|
||||
|
||||
@implementation PBTextFormat
|
||||
|
||||
|
||||
BOOL allZeroes(NSString* string);
|
||||
BOOL allZeroes(NSString* string) {
|
||||
for (int i = 0; i < (int32_t)string.length; i++) {
|
||||
if ([string characterAtIndex:(NSUInteger)i] != '0') {
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
|
||||
/** Is this an octal digit? */
|
||||
BOOL isOctal(unichar c);
|
||||
BOOL isOctal(unichar c) {
|
||||
return '0' <= c && c <= '7';
|
||||
}
|
||||
|
||||
|
||||
/** Is this an octal digit? */
|
||||
BOOL isDecimal(unichar c);
|
||||
BOOL isDecimal(unichar c) {
|
||||
return '0' <= c && c <= '9';
|
||||
}
|
||||
|
||||
/** Is this a hex digit? */
|
||||
BOOL isHex(unichar c);
|
||||
BOOL isHex(unichar c) {
|
||||
return
|
||||
isDecimal(c) ||
|
||||
('a' <= c && c <= 'f') ||
|
||||
('A' <= c && c <= 'F');
|
||||
}
|
||||
|
||||
|
||||
+ (int64_t) parseInteger:(NSString*) text
|
||||
isSigned:(BOOL) isSigned
|
||||
isLong:(BOOL) isLong {
|
||||
if (text.length == 0) {
|
||||
@throw [NSException exceptionWithName:@"NumberFormat" reason:@"Number was blank" userInfo:nil];
|
||||
}
|
||||
|
||||
if (isblank([text characterAtIndex:0])) {
|
||||
@throw [NSException exceptionWithName:@"NumberFormat" reason:@"Invalid character" userInfo:nil];
|
||||
}
|
||||
|
||||
if ([text hasPrefix:@"-"]) {
|
||||
if (!isSigned) {
|
||||
@throw [NSException exceptionWithName:@"NumberFormat" reason:@"Number must be positive" userInfo:nil];
|
||||
}
|
||||
}
|
||||
|
||||
// now call into the appropriate conversion utilities.
|
||||
int64_t result;
|
||||
const char* in_string = text.UTF8String;
|
||||
char* out_string = NULL;
|
||||
errno = 0;
|
||||
if (isLong) {
|
||||
if (isSigned) {
|
||||
result = strtoll(in_string, &out_string, 0);
|
||||
} else {
|
||||
result = convertUInt64ToInt64(strtoull(in_string, &out_string, 0));
|
||||
}
|
||||
} else {
|
||||
if (isSigned) {
|
||||
result = strtol(in_string, &out_string, 0);
|
||||
} else {
|
||||
result = convertUInt32ToInt32((unsigned int)strtoul(in_string, &out_string, 0));
|
||||
}
|
||||
}
|
||||
|
||||
// from the man pages:
|
||||
// (Thus, i* tr is not `\0' but **endptr is `\0' on return, the entire
|
||||
// string was valid.)
|
||||
if (*in_string == 0 || *out_string != 0) {
|
||||
@throw [NSException exceptionWithName:@"NumberFormat" reason:@"IllegalNumber" userInfo:nil];
|
||||
}
|
||||
|
||||
if (errno == ERANGE) {
|
||||
@throw [NSException exceptionWithName:@"NumberFormat" reason:@"Number out of range" userInfo:nil];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parse a 32-bit signed integer from the text. This function recognizes
|
||||
* the prefixes "0x" and "0" to signify hexidecimal and octal numbers,
|
||||
* respectively.
|
||||
*/
|
||||
+ (int32_t) parseInt32:(NSString*) text {
|
||||
return (int32_t)[self parseInteger:text isSigned:YES isLong:NO];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parse a 32-bit unsigned integer from the text. This function recognizes
|
||||
* the prefixes "0x" and "0" to signify hexidecimal and octal numbers,
|
||||
* respectively. The result is coerced to a (signed) {@code int} when returned.
|
||||
*/
|
||||
+ (int32_t) parseUInt32:(NSString*) text {
|
||||
return (int32_t)[self parseInteger:text isSigned:NO isLong:NO];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parse a 64-bit signed integer from the text. This function recognizes
|
||||
* the prefixes "0x" and "0" to signify hexidecimal and octal numbers,
|
||||
* respectively.
|
||||
*/
|
||||
+ (int64_t) parseInt64:(NSString*) text {
|
||||
return [self parseInteger:text isSigned:YES isLong:YES];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parse a 64-bit unsigned integer from the text. This function recognizes
|
||||
* the prefixes "0x" and "0" to signify hexidecimal and octal numbers,
|
||||
* respectively. The result is coerced to a (signed) {@code long} when
|
||||
* returned.
|
||||
*/
|
||||
+ (int64_t) parseUInt64:(NSString*) text {
|
||||
return [self parseInteger:text isSigned:NO isLong:YES];
|
||||
}
|
||||
|
||||
/**
|
||||
* Interpret a character as a digit (in any base up to 36) and return the
|
||||
* numeric value. This is like {@code Character.digit()} but we don't accept
|
||||
* non-ASCII digits.
|
||||
*/
|
||||
int32_t digitValue(unichar c);
|
||||
int32_t digitValue(unichar c) {
|
||||
if ('0' <= c && c <= '9') {
|
||||
return c - '0';
|
||||
} else if ('a' <= c && c <= 'z') {
|
||||
return c - 'a' + 10;
|
||||
} else {
|
||||
return c - 'A' + 10;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Un-escape a byte sequence as escaped using
|
||||
* {@link #escapeBytes(ByteString)}. Two-digit hex escapes (starting with
|
||||
* "\x") are also recognized.
|
||||
*/
|
||||
+ (NSData*) unescapeBytes:(NSString*) input {
|
||||
NSMutableData* result = [NSMutableData dataWithLength:input.length];
|
||||
|
||||
int32_t pos = 0;
|
||||
for (int32_t i = 0; i < (int32_t)input.length; i++) {
|
||||
unichar c = [input characterAtIndex:(NSUInteger)i];
|
||||
if (c == '\\') {
|
||||
if (i + 1 < (int32_t)input.length) {
|
||||
++i;
|
||||
c = [input characterAtIndex:(NSUInteger)i];
|
||||
if (isOctal(c)) {
|
||||
// Octal escape.
|
||||
int32_t code = digitValue(c);
|
||||
if (i + 1 < (int32_t)input.length && isOctal([input characterAtIndex:(NSUInteger)(i + 1)])) {
|
||||
++i;
|
||||
code = code * 8 + digitValue([input characterAtIndex:(NSUInteger)i]);
|
||||
}
|
||||
if (i + 1 < (int32_t)input.length && isOctal([input characterAtIndex:(NSUInteger)(i + 1)])) {
|
||||
++i;
|
||||
code = code * 8 + digitValue([input characterAtIndex:(NSUInteger)i]);
|
||||
}
|
||||
((int8_t*)result.mutableBytes)[pos++] = (int8_t)code;
|
||||
} else {
|
||||
switch (c) {
|
||||
case 'a' : ((int8_t*)result.mutableBytes)[pos++] = 0x07; break;
|
||||
case 'b' : ((int8_t*)result.mutableBytes)[pos++] = '\b'; break;
|
||||
case 'f' : ((int8_t*)result.mutableBytes)[pos++] = '\f'; break;
|
||||
case 'n' : ((int8_t*)result.mutableBytes)[pos++] = '\n'; break;
|
||||
case 'r' : ((int8_t*)result.mutableBytes)[pos++] = '\r'; break;
|
||||
case 't' : ((int8_t*)result.mutableBytes)[pos++] = '\t'; break;
|
||||
case 'v' : ((int8_t*)result.mutableBytes)[pos++] = 0x0b; break;
|
||||
case '\\': ((int8_t*)result.mutableBytes)[pos++] = '\\'; break;
|
||||
case '\'': ((int8_t*)result.mutableBytes)[pos++] = '\''; break;
|
||||
case '"' : ((int8_t*)result.mutableBytes)[pos++] = '\"'; break;
|
||||
|
||||
case 'x': // hex escape
|
||||
{
|
||||
int32_t code = 0;
|
||||
if (i + 1 < (int32_t)input.length && isHex([input characterAtIndex:(NSUInteger)(i + 1)])) {
|
||||
++i;
|
||||
code = digitValue([input characterAtIndex:(NSUInteger)i]);
|
||||
} else {
|
||||
@throw [NSException exceptionWithName:@"InvalidEscape" reason:@"Invalid escape sequence: '\\x' with no digits" userInfo:nil];
|
||||
}
|
||||
if (i + 1 < (int32_t)input.length && isHex([input characterAtIndex:(NSUInteger)(i + 1)])) {
|
||||
++i;
|
||||
code = code * 16 + digitValue([input characterAtIndex:(NSUInteger)i]);
|
||||
}
|
||||
((int8_t*)result.mutableBytes)[pos++] = (int8_t)code;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
@throw [NSException exceptionWithName:@"InvalidEscape" reason:@"Invalid escape sequence" userInfo:nil];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@throw [NSException exceptionWithName:@"InvalidEscape" reason:@"Invalid escape sequence: '\\' at end of string" userInfo:nil];
|
||||
}
|
||||
} else {
|
||||
((int8_t*)result.mutableBytes)[pos++] = (int8_t)c;
|
||||
}
|
||||
}
|
||||
|
||||
[result setLength:(NSUInteger)pos];
|
||||
return result;
|
||||
}
|
||||
|
||||
@end
|
|
@ -1,45 +0,0 @@
|
|||
// 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.
|
||||
|
||||
@class PBUnknownFieldSet_Builder;
|
||||
@class PBUnknownFieldSet;
|
||||
@class PBField;
|
||||
@class PBCodedOutputStream;
|
||||
|
||||
@interface PBUnknownFieldSet : NSObject {
|
||||
@private
|
||||
NSDictionary* fields;
|
||||
}
|
||||
|
||||
@property (readonly, retain) NSDictionary* fields;
|
||||
|
||||
+ (PBUnknownFieldSet*) defaultInstance;
|
||||
|
||||
+ (PBUnknownFieldSet*) setWithFields:(NSMutableDictionary*) fields;
|
||||
+ (PBUnknownFieldSet*) parseFromData:(NSData*) data;
|
||||
|
||||
+ (PBUnknownFieldSet_Builder*) builder;
|
||||
+ (PBUnknownFieldSet_Builder*) builderWithUnknownFields:(PBUnknownFieldSet*) other;
|
||||
|
||||
- (void) writeAsMessageSetTo:(PBCodedOutputStream*) output;
|
||||
- (void) writeToCodedOutputStream:(PBCodedOutputStream*) output;
|
||||
- (NSData*) data;
|
||||
|
||||
- (int32_t) serializedSize;
|
||||
- (int32_t) serializedSizeAsMessageSet;
|
||||
|
||||
- (BOOL) hasField:(int32_t) number;
|
||||
- (PBField*) getField:(int32_t) number;
|
||||
|
||||
@end
|
|
@ -1,161 +0,0 @@
|
|||
// 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.h"
|
||||
|
||||
#import "CodedInputStream.h"
|
||||
#import "CodedOutputStream.h"
|
||||
#import "Field.h"
|
||||
#import "UnknownFieldSet_Builder.h"
|
||||
|
||||
@interface PBUnknownFieldSet()
|
||||
@property (retain) NSDictionary* fields;
|
||||
@end
|
||||
|
||||
|
||||
@implementation PBUnknownFieldSet
|
||||
|
||||
static PBUnknownFieldSet* defaultInstance = nil;
|
||||
|
||||
+ (void) initialize {
|
||||
if (self == [PBUnknownFieldSet class]) {
|
||||
defaultInstance = [PBUnknownFieldSet setWithFields:[NSMutableDictionary dictionary]];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@synthesize fields;
|
||||
|
||||
- (void) dealloc {
|
||||
self.fields = nil;
|
||||
}
|
||||
|
||||
|
||||
+ (PBUnknownFieldSet*) defaultInstance {
|
||||
return defaultInstance;
|
||||
}
|
||||
|
||||
|
||||
- (id) initWithFields:(NSMutableDictionary*) fields_ {
|
||||
if ((self = [super init])) {
|
||||
self.fields = fields_;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
+ (PBUnknownFieldSet*) setWithFields:(NSMutableDictionary*) fields {
|
||||
return [[PBUnknownFieldSet alloc] initWithFields:fields];
|
||||
}
|
||||
|
||||
|
||||
- (BOOL) hasField:(int32_t) number {
|
||||
return [fields objectForKey:[NSNumber numberWithInt:number]] != nil;
|
||||
}
|
||||
|
||||
|
||||
- (PBField*) getField:(int32_t) number {
|
||||
PBField* result = [fields objectForKey:[NSNumber numberWithInt:number]];
|
||||
return (result == nil) ? [PBField defaultInstance] : result;
|
||||
}
|
||||
|
||||
|
||||
- (void) writeToCodedOutputStream:(PBCodedOutputStream*) output {
|
||||
NSArray* sortedKeys = [fields.allKeys sortedArrayUsingSelector:@selector(compare:)];
|
||||
for (NSNumber* number in sortedKeys) {
|
||||
PBField* value = [fields objectForKey:number];
|
||||
[value writeTo:number.intValue output:output];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (void) writeToOutputStream:(NSOutputStream*) output {
|
||||
PBCodedOutputStream* codedOutput = [PBCodedOutputStream streamWithOutputStream:output];
|
||||
[self writeToCodedOutputStream:codedOutput];
|
||||
[codedOutput flush];
|
||||
}
|
||||
|
||||
|
||||
+ (PBUnknownFieldSet*) parseFromCodedInputStream:(PBCodedInputStream*) input {
|
||||
return [[[PBUnknownFieldSet builder] mergeFromCodedInputStream:input] build];
|
||||
}
|
||||
|
||||
|
||||
+ (PBUnknownFieldSet*) parseFromData:(NSData*) data {
|
||||
return [[[PBUnknownFieldSet builder] mergeFromData:data] build];
|
||||
}
|
||||
|
||||
|
||||
+ (PBUnknownFieldSet*) parseFromInputStream:(NSInputStream*) input {
|
||||
return [[[PBUnknownFieldSet builder] mergeFromInputStream:input] build];
|
||||
}
|
||||
|
||||
|
||||
+ (PBUnknownFieldSet_Builder*) builder {
|
||||
return [[PBUnknownFieldSet_Builder alloc] init];
|
||||
}
|
||||
|
||||
|
||||
+ (PBUnknownFieldSet_Builder*) builderWithUnknownFields:(PBUnknownFieldSet*) copyFrom {
|
||||
return [[PBUnknownFieldSet builder] mergeUnknownFields:copyFrom];
|
||||
}
|
||||
|
||||
|
||||
/** Get the number of bytes required to encode this set. */
|
||||
- (int32_t) serializedSize {
|
||||
int32_t result = 0;
|
||||
for (NSNumber* number in fields) {
|
||||
result += [[fields objectForKey:number] getSerializedSize:number.intValue];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Serializes the set and writes it to {@code output} using
|
||||
* {@code MessageSet} wire format.
|
||||
*/
|
||||
- (void) writeAsMessageSetTo:(PBCodedOutputStream*) output {
|
||||
for (NSNumber* number in fields) {
|
||||
[[fields objectForKey:number] writeAsMessageSetExtensionTo:number.intValue output:output];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the number of bytes required to encode this set using
|
||||
* {@code MessageSet} wire format.
|
||||
*/
|
||||
- (int32_t) serializedSizeAsMessageSet {
|
||||
int32_t result = 0;
|
||||
for (NSNumber* number in fields) {
|
||||
result += [[fields objectForKey:number] getSerializedSizeAsMessageSetExtension:number.intValue];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Serializes the message to a {@code ByteString} and returns it. This is
|
||||
* just a trivial wrapper around {@link #writeTo(PBCodedOutputStream)}.
|
||||
*/
|
||||
- (NSData*) data {
|
||||
NSMutableData* data = [NSMutableData dataWithLength:(NSUInteger)self.serializedSize];
|
||||
PBCodedOutputStream* output = [PBCodedOutputStream streamWithData:data];
|
||||
|
||||
[self writeToCodedOutputStream:output];
|
||||
return data;
|
||||
}
|
||||
|
||||
@end
|
|
@ -1,51 +0,0 @@
|
|||
// 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.
|
||||
|
||||
@class PBField;
|
||||
@class PBMutableField;
|
||||
@class PBUnknownFieldSet;
|
||||
@class PBUnknownFieldSet_Builder;
|
||||
@class PBCodedInputStream;
|
||||
|
||||
@interface PBUnknownFieldSet_Builder : NSObject {
|
||||
@private
|
||||
NSMutableDictionary* fields;
|
||||
|
||||
// Optimization: We keep around a builder for the last field that was
|
||||
// modified so that we can efficiently add to it multiple times in a
|
||||
// row (important when parsing an unknown repeated field).
|
||||
int32_t lastFieldNumber;
|
||||
|
||||
PBMutableField* lastField;
|
||||
}
|
||||
|
||||
+ (PBUnknownFieldSet_Builder*) newBuilder:(PBUnknownFieldSet*) unknownFields;
|
||||
|
||||
- (PBUnknownFieldSet*) build;
|
||||
- (PBUnknownFieldSet_Builder*) mergeUnknownFields:(PBUnknownFieldSet*) other;
|
||||
|
||||
- (PBUnknownFieldSet_Builder*) mergeFromCodedInputStream:(PBCodedInputStream*) input;
|
||||
- (PBUnknownFieldSet_Builder*) mergeFromData:(NSData*) data;
|
||||
- (PBUnknownFieldSet_Builder*) mergeFromInputStream:(NSInputStream*) input;
|
||||
|
||||
- (PBUnknownFieldSet_Builder*) mergeVarintField:(int32_t) number value:(int32_t) value;
|
||||
|
||||
- (BOOL) mergeFieldFrom:(int32_t) tag input:(PBCodedInputStream*) input;
|
||||
|
||||
- (PBUnknownFieldSet_Builder*) addField:(PBField*) field forNumber:(int32_t) number;
|
||||
|
||||
- (PBUnknownFieldSet_Builder*) clear;
|
||||
- (PBUnknownFieldSet_Builder*) mergeField:(PBField*) field forNumber:(int32_t) number;
|
||||
|
||||
@end
|
|
@ -1,237 +0,0 @@
|
|||
// 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
|
|
@ -1,26 +0,0 @@
|
|||
// 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.
|
||||
|
||||
int64_t convertFloat64ToInt64(Float64 f);
|
||||
int32_t convertFloat32ToInt32(Float32 f);
|
||||
Float64 convertInt64ToFloat64(int64_t f);
|
||||
Float32 convertInt32ToFloat32(int32_t f);
|
||||
|
||||
uint64_t convertInt64ToUInt64(int64_t i);
|
||||
int64_t convertUInt64ToInt64(uint64_t u);
|
||||
uint32_t convertInt32ToUInt32(int32_t i);
|
||||
int64_t convertUInt32ToInt32(uint32_t u);
|
||||
|
||||
int32_t logicalRightShift32(int32_t value, int32_t spaces);
|
||||
int64_t logicalRightShift64(int64_t value, int32_t spaces);
|
|
@ -1,79 +0,0 @@
|
|||
// 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 "Utilities.h"
|
||||
|
||||
int64_t convertFloat64ToInt64(Float64 v) {
|
||||
union { Float64 f; int64_t i; } u;
|
||||
u.f = v;
|
||||
return u.i;
|
||||
}
|
||||
|
||||
|
||||
int32_t convertFloat32ToInt32(Float32 v) {
|
||||
union { Float32 f; int32_t i; } u;
|
||||
u.f = v;
|
||||
return u.i;
|
||||
}
|
||||
|
||||
|
||||
Float64 convertInt64ToFloat64(int64_t v) {
|
||||
union { Float64 f; int64_t i; } u;
|
||||
u.i = v;
|
||||
return u.f;
|
||||
}
|
||||
|
||||
|
||||
Float32 convertInt32ToFloat32(int32_t v) {
|
||||
union { Float32 f; int32_t i; } u;
|
||||
u.i = v;
|
||||
return u.f;
|
||||
}
|
||||
|
||||
|
||||
uint64_t convertInt64ToUInt64(int64_t v) {
|
||||
union { int64_t i; uint64_t u; } u;
|
||||
u.i = v;
|
||||
return u.u;
|
||||
}
|
||||
|
||||
|
||||
int64_t convertUInt64ToInt64(uint64_t v) {
|
||||
union { int64_t i; uint64_t u; } u;
|
||||
u.u = v;
|
||||
return u.i;
|
||||
}
|
||||
|
||||
uint32_t convertInt32ToUInt32(int32_t v) {
|
||||
union { int32_t i; uint32_t u; } u;
|
||||
u.i = v;
|
||||
return u.u;
|
||||
}
|
||||
|
||||
|
||||
int64_t convertUInt32ToInt32(uint32_t v) {
|
||||
union { int32_t i; uint32_t u; } u;
|
||||
u.u = v;
|
||||
return u.i;
|
||||
}
|
||||
|
||||
|
||||
int32_t logicalRightShift32(int32_t value, int32_t spaces) {
|
||||
return (int32_t)convertUInt32ToInt32((convertInt32ToUInt32(value) >> spaces));
|
||||
}
|
||||
|
||||
|
||||
int64_t logicalRightShift64(int64_t value, int32_t spaces) {
|
||||
return convertUInt64ToInt64((convertInt64ToUInt64(value) >> spaces));
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
// 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.
|
||||
|
||||
typedef enum {
|
||||
PBWireFormatVarint = 0,
|
||||
PBWireFormatFixed64 = 1,
|
||||
PBWireFormatLengthDelimited = 2,
|
||||
PBWireFormatStartGroup = 3,
|
||||
PBWireFormatEndGroup = 4,
|
||||
PBWireFormatFixed32 = 5,
|
||||
|
||||
PBWireFormatTagTypeBits = 3,
|
||||
PBWireFormatTagTypeMask = 7 /* = (1 << PBWireFormatTagTypeBits) - 1*/,
|
||||
|
||||
PBWireFormatMessageSetItem = 1,
|
||||
PBWireFormatMessageSetTypeId = 2,
|
||||
PBWireFormatMessageSetMessage = 3
|
||||
} PBWireFormat;
|
||||
|
||||
int32_t PBWireFormatMakeTag(int32_t fieldNumber, int32_t wireType);
|
||||
int32_t PBWireFormatGetTagWireType(int32_t tag);
|
||||
int32_t PBWireFormatGetTagFieldNumber(int32_t tag);
|
||||
|
||||
#define PBWireFormatMessageSetItemTag (PBWireFormatMakeTag(PBWireFormatMessageSetItem, PBWireFormatStartGroup))
|
||||
#define PBWireFormatMessageSetItemEndTag (PBWireFormatMakeTag(PBWireFormatMessageSetItem, PBWireFormatEndGroup))
|
||||
#define PBWireFormatMessageSetTypeIdTag (PBWireFormatMakeTag(PBWireFormatMessageSetTypeId, PBWireFormatVarint))
|
||||
#define PBWireFormatMessageSetMessageTag (PBWireFormatMakeTag(PBWireFormatMessageSetMessage, PBWireFormatLengthDelimited))
|
|
@ -1,31 +0,0 @@
|
|||
// 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 "WireFormat.h"
|
||||
|
||||
#import "Utilities.h"
|
||||
|
||||
int32_t PBWireFormatMakeTag(int32_t fieldNumber, int32_t wireType) {
|
||||
return (fieldNumber << PBWireFormatTagTypeBits) | wireType;
|
||||
}
|
||||
|
||||
|
||||
int32_t PBWireFormatGetTagWireType(int32_t tag) {
|
||||
return tag & PBWireFormatTagTypeMask;
|
||||
}
|
||||
|
||||
|
||||
int32_t PBWireFormatGetTagFieldNumber(int32_t tag) {
|
||||
return logicalRightShift32(tag, PBWireFormatTagTypeBits);
|
||||
}
|
9
Podfile
|
@ -1,14 +1,19 @@
|
|||
platform :ios, '7.0'
|
||||
source 'https://github.com/CocoaPods/Specs.git'
|
||||
inhibit_all_warnings!
|
||||
|
||||
link_with ["Signal", "SignalTests"]
|
||||
|
||||
pod 'UICKeyChainStore', :podspec => 'Podspecs/UICKeyChainStore.podspec'
|
||||
pod 'SocketRocket', :git => 'https://github.com/square/SocketRocket.git', :commit => 'd0585af165'
|
||||
pod 'OpenSSL', '~> 1.0.109'
|
||||
pod 'MMDrawerController', '~> 0.5.7'
|
||||
pod 'libPhoneNumber-iOS', '~> 0.7'
|
||||
pod 'AxolotlKit', '~> 0.1'
|
||||
pod 'PastelogKit', '~> 1.2'
|
||||
pod 'AFNetworking', '~> 2.4.1'
|
||||
pod 'TwistedOakCollapsingFutures','~> 1.0'
|
||||
pod 'YapDatabase/SQLCipher'
|
||||
pod 'AFNetworking', '~> 2.4'
|
||||
pod 'Mantle', '~> 1.5'
|
||||
|
||||
pod 'JSQMessagesViewController', :git => 'https://github.com/dtsbourg/JSQMessagesViewController', :branch => 'JSignalQ'
|
||||
pod 'DJWActionSheet'
|
||||
|
|
102
Podfile.lock
|
@ -1,85 +1,113 @@
|
|||
PODS:
|
||||
- AFNetworking (2.4.1):
|
||||
- AFNetworking/NSURLConnection
|
||||
- AFNetworking/NSURLSession
|
||||
- AFNetworking/Reachability
|
||||
- AFNetworking/Security
|
||||
- AFNetworking/Serialization
|
||||
- AFNetworking/UIKit
|
||||
- AFNetworking/NSURLConnection (2.4.1):
|
||||
- AFNetworking/Reachability
|
||||
- AFNetworking/Security
|
||||
- AFNetworking/Serialization
|
||||
- AFNetworking/NSURLSession (2.4.1):
|
||||
- AFNetworking/Reachability
|
||||
- AFNetworking/Security
|
||||
- AFNetworking/Serialization
|
||||
- AFNetworking/Reachability (2.4.1)
|
||||
- AFNetworking/Security (2.4.1)
|
||||
- AFNetworking/Serialization (2.4.1)
|
||||
- AFNetworking/UIKit (2.4.1):
|
||||
- 25519 (1.8)
|
||||
- AFNetworking (2.5.0):
|
||||
- AFNetworking/NSURLConnection (= 2.5.0)
|
||||
- AFNetworking/NSURLSession (= 2.5.0)
|
||||
- AFNetworking/Reachability (= 2.5.0)
|
||||
- AFNetworking/Security (= 2.5.0)
|
||||
- AFNetworking/Serialization (= 2.5.0)
|
||||
- AFNetworking/UIKit (= 2.5.0)
|
||||
- AFNetworking/NSURLConnection (2.5.0):
|
||||
- AFNetworking/Reachability
|
||||
- AFNetworking/Security
|
||||
- AFNetworking/Serialization
|
||||
- AFNetworking/NSURLSession (2.5.0):
|
||||
- AFNetworking/Reachability
|
||||
- AFNetworking/Security
|
||||
- AFNetworking/Serialization
|
||||
- AFNetworking/Reachability (2.5.0)
|
||||
- AFNetworking/Security (2.5.0)
|
||||
- AFNetworking/Serialization (2.5.0)
|
||||
- AFNetworking/UIKit (2.5.0):
|
||||
- AFNetworking/NSURLConnection
|
||||
- AFNetworking/NSURLSession
|
||||
- AxolotlKit (0.1):
|
||||
- 25519 (~> 1.8)
|
||||
- HKDFKit (~> 0.0.3)
|
||||
- ProtocolBuffers (~> 1.9.2)
|
||||
- CocoaLumberjack (1.9.2):
|
||||
- CocoaLumberjack/Extensions
|
||||
- CocoaLumberjack/Extensions (= 1.9.2)
|
||||
- CocoaLumberjack/Core (1.9.2)
|
||||
- CocoaLumberjack/Extensions (1.9.2):
|
||||
- CocoaLumberjack/Core
|
||||
- DJWActionSheet (1.0.4)
|
||||
- HKDFKit (0.0.3)
|
||||
- JSQMessagesViewController (6.0-beta6):
|
||||
- JSQSystemSoundPlayer (~> 2.0.0)
|
||||
- JSQSystemSoundPlayer (2.0.0)
|
||||
- libPhoneNumber-iOS (0.7.3)
|
||||
- MMDrawerController (0.5.7):
|
||||
- MMDrawerController/Core
|
||||
- MMDrawerController/MMDrawerBarButtonItem
|
||||
- MMDrawerController/MMDrawerVisualStates
|
||||
- MMDrawerController/Subclass
|
||||
- MMDrawerController/Core (0.5.7)
|
||||
- MMDrawerController/MMDrawerBarButtonItem (0.5.7):
|
||||
- MMDrawerController/Core
|
||||
- MMDrawerController/MMDrawerVisualStates (0.5.7):
|
||||
- MMDrawerController/Core
|
||||
- MMDrawerController/Subclass (0.5.7):
|
||||
- MMDrawerController/Core
|
||||
- Mantle (1.5.1):
|
||||
- Mantle/extobjc (= 1.5.1)
|
||||
- Mantle/extobjc (1.5.1)
|
||||
- OpenSSL (1.0.109)
|
||||
- PastelogKit (1.2):
|
||||
- CocoaLumberjack (~> 1.9)
|
||||
- ProtocolBuffers (1.9.2)
|
||||
- SocketRocket (0.3.1-beta2)
|
||||
- SQLCipher/common (3.1.0)
|
||||
- SQLCipher/fts (3.1.0):
|
||||
- SQLCipher/common
|
||||
- TwistedOakCollapsingFutures (1.0.0):
|
||||
- UnionFind (~> 1.0)
|
||||
- UICKeyChainStore (1.0.7)
|
||||
- UnionFind (1.0.1)
|
||||
- YapDatabase/common (2.5.3):
|
||||
- CocoaLumberjack (~> 1)
|
||||
- YapDatabase/SQLCipher (2.5.3):
|
||||
- SQLCipher/fts
|
||||
- YapDatabase/common
|
||||
|
||||
DEPENDENCIES:
|
||||
- AFNetworking (~> 2.4.1)
|
||||
- AFNetworking (~> 2.4)
|
||||
- AxolotlKit (~> 0.1)
|
||||
- DJWActionSheet
|
||||
- JSQMessagesViewController (from `https://github.com/dtsbourg/JSQMessagesViewController`, branch `JSignalQ`)
|
||||
- libPhoneNumber-iOS (~> 0.7)
|
||||
- MMDrawerController (~> 0.5.7)
|
||||
- Mantle (~> 1.5)
|
||||
- OpenSSL (~> 1.0.109)
|
||||
- PastelogKit (~> 1.2)
|
||||
- SocketRocket (from `https://github.com/square/SocketRocket.git`, commit `d0585af165`)
|
||||
- TwistedOakCollapsingFutures (~> 1.0)
|
||||
- UICKeyChainStore (from `Podspecs/UICKeyChainStore.podspec`)
|
||||
- YapDatabase/SQLCipher
|
||||
|
||||
EXTERNAL SOURCES:
|
||||
JSQMessagesViewController:
|
||||
:branch: JSignalQ
|
||||
:git: https://github.com/dtsbourg/JSQMessagesViewController
|
||||
SocketRocket:
|
||||
:commit: d0585af165
|
||||
:git: https://github.com/square/SocketRocket.git
|
||||
UICKeyChainStore:
|
||||
:podspec: Podspecs/UICKeyChainStore.podspec
|
||||
|
||||
CHECKOUT OPTIONS:
|
||||
JSQMessagesViewController:
|
||||
:commit: 21d877492e948f27fde4115573a809798cc78210
|
||||
:git: https://github.com/dtsbourg/JSQMessagesViewController
|
||||
SocketRocket:
|
||||
:commit: d0585af165
|
||||
:git: https://github.com/square/SocketRocket.git
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
AFNetworking: 0aabc6fae66d6e5d039eeb21c315843c7aae51ab
|
||||
25519: 601ffb5d258aa33d642062d6fa4096db210e02e7
|
||||
AFNetworking: 0f54cb5d16ce38c1b76948faffb8d5fb705021c7
|
||||
AxolotlKit: 395c3302e840a1b9f053e9733002d586d4b10ce0
|
||||
CocoaLumberjack: 205769c032b5fef85b92472046bcc8b7e7c8a817
|
||||
DJWActionSheet: d88b302d7c29523e1e9fb9b62cfac46f59bb90d9
|
||||
HKDFKit: 5998cf1bbb611e7ecc6bd3eaaef8c7a7da7be949
|
||||
JSQMessagesViewController: 960a09d11978bea52d1a676e97980838f8d98652
|
||||
JSQSystemSoundPlayer: c98443b1cbb3b45db09d0d3d6c2355cf78294981
|
||||
libPhoneNumber-iOS: 98fc07d70c8fdb5e6a8e3442c37e97353065c20e
|
||||
MMDrawerController: c3ab7a318ddc7e2bcd133139c3161af08c6e1197
|
||||
Mantle: d7c5ac734579ec751c58fecbf56189853056c58c
|
||||
OpenSSL: 4810adf5c99b0e2cd20670a11a987c805e8a521c
|
||||
PastelogKit: 8bab71b1d187617a83e7124cffe9eb1a600e6695
|
||||
ProtocolBuffers: a834d6fe4ae0cc94d081b864e4948bdd483ad228
|
||||
SocketRocket: 9cbe08469513356cddc0afcab1ff160bd190296a
|
||||
SQLCipher: 981110217eb93c2779c34fb59e646a1c1da918d8
|
||||
TwistedOakCollapsingFutures: 07aab84fd3958dc94d55ef705b12857d9fbe61d1
|
||||
UICKeyChainStore: eef407137f0397e95a3df32cdf05f7e2ddd99647
|
||||
UnionFind: 45777a8b6878d3a602af3654cc3a09b87389d356
|
||||
YapDatabase: 096e860167b04e629b88bea33dfb7a4153279bb0
|
||||
|
||||
COCOAPODS: 0.34.4
|
||||
COCOAPODS: 0.35.0
|
||||
|
|
Before Width: | Height: | Size: 7.7 KiB After Width: | Height: | Size: 7.7 KiB |
Before Width: | Height: | Size: 8.1 KiB After Width: | Height: | Size: 8.1 KiB |
Before Width: | Height: | Size: 8.5 KiB After Width: | Height: | Size: 8.5 KiB |
Before Width: | Height: | Size: 6.3 KiB After Width: | Height: | Size: 6.3 KiB |
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 3.4 KiB |
Before Width: | Height: | Size: 888 B After Width: | Height: | Size: 888 B |
Before Width: | Height: | Size: 5.0 KiB After Width: | Height: | Size: 5.0 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.9 KiB |
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 8.0 KiB After Width: | Height: | Size: 8.0 KiB |
Before Width: | Height: | Size: 6.4 KiB After Width: | Height: | Size: 6.4 KiB |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 674 B After Width: | Height: | Size: 674 B |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 5.6 KiB After Width: | Height: | Size: 5.6 KiB |
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 52 KiB |
Before Width: | Height: | Size: 6.2 KiB After Width: | Height: | Size: 6.2 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.6 KiB |
Before Width: | Height: | Size: 6.1 KiB After Width: | Height: | Size: 6.1 KiB |
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.9 KiB |
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.5 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 9.7 KiB After Width: | Height: | Size: 9.7 KiB |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 5.7 KiB After Width: | Height: | Size: 5.7 KiB |
Before Width: | Height: | Size: 781 B After Width: | Height: | Size: 781 B |
Before Width: | Height: | Size: 8.9 KiB After Width: | Height: | Size: 8.9 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
|
@ -50,8 +50,6 @@
|
|||
</array>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
<string>Storyboard</string>
|
||||
<key>UIMainStoryboardFile</key>
|
||||
<string>Storyboard</string>
|
||||
<key>UIRequiredDeviceCapabilities</key>
|
||||
<array>
|
||||
<string>armv7</string>
|
||||
|
|
|
@ -1,25 +1,23 @@
|
|||
#import "AppDelegate.h"
|
||||
#import "AppAudioManager.h"
|
||||
#import "CallLogViewController.h"
|
||||
#import "CategorizingLogger.h"
|
||||
#import "DebugLogger.h"
|
||||
#import "DialerViewController.h"
|
||||
#import "DiscardingLog.h"
|
||||
#import "Environment.h"
|
||||
#import "InCallViewController.h"
|
||||
#import "LeftSideMenuViewController.h"
|
||||
#import "MMDrawerController.h"
|
||||
#import "PreferencesUtil.h"
|
||||
#import "NotificationTracker.h"
|
||||
#import "PushManager.h"
|
||||
#import "PriorityQueue.h"
|
||||
#import "RecentCallManager.h"
|
||||
#import "Release.h"
|
||||
#import "SettingsViewController.h"
|
||||
#import "TabBarParentViewController.h"
|
||||
#import "Util.h"
|
||||
#import "VersionMigrations.h"
|
||||
|
||||
#import "InitialViewController.h"
|
||||
|
||||
|
||||
#import <PastelogKit/Pastelog.h>
|
||||
|
||||
#define kSignalVersionKey @"SignalUpdateVersionKey"
|
||||
|
@ -31,7 +29,6 @@
|
|||
@interface AppDelegate ()
|
||||
|
||||
@property (nonatomic, retain) UIWindow *blankWindow;
|
||||
@property (nonatomic, strong) MMDrawerController *drawerController;
|
||||
@property (nonatomic, strong) NotificationTracker *notificationTracker;
|
||||
|
||||
@property (nonatomic) TOCFutureSource *callPickUpFuture;
|
||||
|
@ -139,12 +136,6 @@
|
|||
[Environment.getCurrent.contactsManager doAfterEnvironmentInitSetup];
|
||||
[UIApplication.sharedApplication setStatusBarStyle:UIStatusBarStyleDefault];
|
||||
|
||||
LeftSideMenuViewController *leftSideMenuViewController = [LeftSideMenuViewController new];
|
||||
|
||||
self.drawerController = [[MMDrawerController alloc] initWithCenterViewController:leftSideMenuViewController.centerTabBarViewController leftDrawerViewController:leftSideMenuViewController];
|
||||
//self.window.rootViewController = _drawerController;
|
||||
//[self.window makeKeyAndVisible];
|
||||
|
||||
//Accept push notification when app is not open
|
||||
NSDictionary *remoteNotif = launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey];
|
||||
if (remoteNotif) {
|
||||
|
@ -169,10 +160,24 @@
|
|||
}
|
||||
}];
|
||||
}
|
||||
[_drawerController.centerViewController presentViewController:callViewController animated:YES completion:nil];
|
||||
|
||||
|
||||
} onThread:NSThread.mainThread untilCancelled:nil];
|
||||
|
||||
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Storyboard" bundle:nil];
|
||||
|
||||
InitialViewController *viewControllerForNewUser = [storyboard instantiateViewControllerWithIdentifier:@"UserInitialViewController"];
|
||||
|
||||
UITabBarController *viewController = [storyboard instantiateViewControllerWithIdentifier:@"UserInitialViewController"];
|
||||
|
||||
BOOL isNewUser = NO;
|
||||
if (isNewUser) {
|
||||
self.window.rootViewController = viewControllerForNewUser;
|
||||
} else {
|
||||
self.window.rootViewController = viewController;
|
||||
}
|
||||
|
||||
[self.window makeKeyAndVisible];
|
||||
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<viewControllerLayoutGuide type="bottom" id="7uh-gm-z8v"/>
|
||||
</layoutGuides>
|
||||
<view key="view" contentMode="scaleToFill" id="EFA-Fu-XJm">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="551"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" showsHorizontalScrollIndicator="NO" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="22" sectionFooterHeight="22" translatesAutoresizingMaskIntoConstraints="NO" id="PaA-ol-uQT">
|
||||
|
@ -35,6 +35,9 @@
|
|||
</tableViewCell>
|
||||
</prototypes>
|
||||
<sections/>
|
||||
<variation key="heightClass=regular-widthClass=compact" misplaced="YES">
|
||||
<rect key="frame" x="0.0" y="-44" width="410" height="844"/>
|
||||
</variation>
|
||||
<connections>
|
||||
<outlet property="dataSource" destination="MY2-bB-USa" id="kop-Y6-6DR"/>
|
||||
<outlet property="delegate" destination="MY2-bB-USa" id="vmj-PA-2Od"/>
|
||||
|
@ -114,7 +117,7 @@
|
|||
<viewControllerLayoutGuide type="bottom" id="stV-ob-KSQ"/>
|
||||
</layoutGuides>
|
||||
<view key="view" contentMode="scaleToFill" id="5r3-kq-bbI">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="551"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</view>
|
||||
|
@ -273,14 +276,14 @@ FA 9C E3 A0 09 9A FF A8 8A 09 99</string>
|
|||
</constraints>
|
||||
<variation key="default">
|
||||
<mask key="constraints">
|
||||
<exclude reference="Nfl-jf-HzC"/>
|
||||
<exclude reference="5IR-xd-6uL"/>
|
||||
<exclude reference="Nfl-jf-HzC"/>
|
||||
</mask>
|
||||
</variation>
|
||||
<variation key="heightClass=regular-widthClass=compact">
|
||||
<mask key="constraints">
|
||||
<include reference="Nfl-jf-HzC"/>
|
||||
<include reference="5IR-xd-6uL"/>
|
||||
<include reference="Nfl-jf-HzC"/>
|
||||
</mask>
|
||||
</variation>
|
||||
</imageView>
|
||||
|
@ -389,31 +392,23 @@ Lorem ipsum : Quick explanation of Fingerprints</string>
|
|||
<exclude reference="DV4-GV-ZPf"/>
|
||||
</mask>
|
||||
<mask key="constraints">
|
||||
<exclude reference="0cP-F5-N4l"/>
|
||||
<exclude reference="T5m-OK-kvD"/>
|
||||
<exclude reference="oOD-rR-Kfs"/>
|
||||
<exclude reference="C8D-t9-FSO"/>
|
||||
<exclude reference="eWz-aq-FbT"/>
|
||||
<exclude reference="nB5-f9-3f8"/>
|
||||
<exclude reference="SaO-RA-JOe"/>
|
||||
<exclude reference="kgd-eg-JMO"/>
|
||||
<exclude reference="GPR-Uo-6ae"/>
|
||||
<exclude reference="HNM-I2-zyR"/>
|
||||
<exclude reference="Pef-ZF-oW5"/>
|
||||
<exclude reference="gJX-7f-ouT"/>
|
||||
<exclude reference="iJ5-YY-tdi"/>
|
||||
<exclude reference="rdE-nO-pjk"/>
|
||||
<exclude reference="OHR-8T-cxj"/>
|
||||
<exclude reference="htv-7j-iii"/>
|
||||
<exclude reference="kPm-bZ-2O1"/>
|
||||
<exclude reference="Cmp-XH-vDT"/>
|
||||
<exclude reference="VHE-LF-wOx"/>
|
||||
<exclude reference="qbq-AK-HjD"/>
|
||||
<exclude reference="C8D-t9-FSO"/>
|
||||
<exclude reference="eWz-aq-FbT"/>
|
||||
<exclude reference="nB5-f9-3f8"/>
|
||||
<exclude reference="0jD-kP-zTX"/>
|
||||
<exclude reference="5uD-gq-nro"/>
|
||||
<exclude reference="HUa-X1-uUr"/>
|
||||
<exclude reference="WAB-2c-hEF"/>
|
||||
<exclude reference="diH-aS-cqX"/>
|
||||
<exclude reference="Cmp-XH-vDT"/>
|
||||
<exclude reference="VHE-LF-wOx"/>
|
||||
<exclude reference="qbq-AK-HjD"/>
|
||||
<exclude reference="GPR-Uo-6ae"/>
|
||||
<exclude reference="HNM-I2-zyR"/>
|
||||
<exclude reference="Pef-ZF-oW5"/>
|
||||
<exclude reference="E3H-bc-Xz8"/>
|
||||
<exclude reference="Zcv-rw-YqP"/>
|
||||
<exclude reference="cp2-OL-5R1"/>
|
||||
|
@ -422,6 +417,14 @@ Lorem ipsum : Quick explanation of Fingerprints</string>
|
|||
<exclude reference="eeg-OU-L4K"/>
|
||||
<exclude reference="jEe-vm-hcC"/>
|
||||
<exclude reference="nL6-9O-tMX"/>
|
||||
<exclude reference="0cP-F5-N4l"/>
|
||||
<exclude reference="T5m-OK-kvD"/>
|
||||
<exclude reference="oOD-rR-Kfs"/>
|
||||
<exclude reference="gJX-7f-ouT"/>
|
||||
<exclude reference="iJ5-YY-tdi"/>
|
||||
<exclude reference="rdE-nO-pjk"/>
|
||||
<exclude reference="SaO-RA-JOe"/>
|
||||
<exclude reference="kgd-eg-JMO"/>
|
||||
</mask>
|
||||
</variation>
|
||||
<variation key="heightClass=regular-widthClass=compact">
|
||||
|
@ -438,31 +441,23 @@ Lorem ipsum : Quick explanation of Fingerprints</string>
|
|||
<include reference="DV4-GV-ZPf"/>
|
||||
</mask>
|
||||
<mask key="constraints">
|
||||
<include reference="0cP-F5-N4l"/>
|
||||
<include reference="T5m-OK-kvD"/>
|
||||
<include reference="oOD-rR-Kfs"/>
|
||||
<include reference="C8D-t9-FSO"/>
|
||||
<include reference="eWz-aq-FbT"/>
|
||||
<include reference="nB5-f9-3f8"/>
|
||||
<include reference="SaO-RA-JOe"/>
|
||||
<include reference="kgd-eg-JMO"/>
|
||||
<include reference="GPR-Uo-6ae"/>
|
||||
<include reference="HNM-I2-zyR"/>
|
||||
<include reference="Pef-ZF-oW5"/>
|
||||
<exclude reference="gJX-7f-ouT"/>
|
||||
<include reference="iJ5-YY-tdi"/>
|
||||
<include reference="rdE-nO-pjk"/>
|
||||
<include reference="OHR-8T-cxj"/>
|
||||
<include reference="htv-7j-iii"/>
|
||||
<include reference="kPm-bZ-2O1"/>
|
||||
<include reference="Cmp-XH-vDT"/>
|
||||
<include reference="VHE-LF-wOx"/>
|
||||
<include reference="qbq-AK-HjD"/>
|
||||
<include reference="C8D-t9-FSO"/>
|
||||
<include reference="eWz-aq-FbT"/>
|
||||
<include reference="nB5-f9-3f8"/>
|
||||
<include reference="0jD-kP-zTX"/>
|
||||
<include reference="5uD-gq-nro"/>
|
||||
<include reference="HUa-X1-uUr"/>
|
||||
<include reference="WAB-2c-hEF"/>
|
||||
<include reference="diH-aS-cqX"/>
|
||||
<include reference="Cmp-XH-vDT"/>
|
||||
<include reference="VHE-LF-wOx"/>
|
||||
<include reference="qbq-AK-HjD"/>
|
||||
<include reference="GPR-Uo-6ae"/>
|
||||
<include reference="HNM-I2-zyR"/>
|
||||
<include reference="Pef-ZF-oW5"/>
|
||||
<exclude reference="E3H-bc-Xz8"/>
|
||||
<include reference="Zcv-rw-YqP"/>
|
||||
<exclude reference="cp2-OL-5R1"/>
|
||||
|
@ -471,6 +466,14 @@ Lorem ipsum : Quick explanation of Fingerprints</string>
|
|||
<include reference="eeg-OU-L4K"/>
|
||||
<exclude reference="jEe-vm-hcC"/>
|
||||
<exclude reference="nL6-9O-tMX"/>
|
||||
<include reference="0cP-F5-N4l"/>
|
||||
<include reference="T5m-OK-kvD"/>
|
||||
<include reference="oOD-rR-Kfs"/>
|
||||
<exclude reference="gJX-7f-ouT"/>
|
||||
<include reference="iJ5-YY-tdi"/>
|
||||
<include reference="rdE-nO-pjk"/>
|
||||
<include reference="SaO-RA-JOe"/>
|
||||
<include reference="kgd-eg-JMO"/>
|
||||
</mask>
|
||||
</variation>
|
||||
</view>
|
||||
|
@ -492,6 +495,7 @@ Lorem ipsum : Quick explanation of Fingerprints</string>
|
|||
<exclude reference="VCu-vN-Pjg"/>
|
||||
</mask>
|
||||
<mask key="constraints">
|
||||
<exclude reference="1dB-W2-GMz"/>
|
||||
<exclude reference="5Wt-QM-aQa"/>
|
||||
<exclude reference="7HF-IV-JbS"/>
|
||||
<exclude reference="KIN-pk-9pP"/>
|
||||
|
@ -499,7 +503,6 @@ Lorem ipsum : Quick explanation of Fingerprints</string>
|
|||
<exclude reference="nEQ-Wa-OyH"/>
|
||||
<exclude reference="sho-vB-Yk8"/>
|
||||
<exclude reference="wdN-bv-bSl"/>
|
||||
<exclude reference="1dB-W2-GMz"/>
|
||||
</mask>
|
||||
</variation>
|
||||
<variation key="heightClass=regular-widthClass=compact">
|
||||
|
@ -507,6 +510,7 @@ Lorem ipsum : Quick explanation of Fingerprints</string>
|
|||
<include reference="VCu-vN-Pjg"/>
|
||||
</mask>
|
||||
<mask key="constraints">
|
||||
<include reference="1dB-W2-GMz"/>
|
||||
<include reference="5Wt-QM-aQa"/>
|
||||
<include reference="7HF-IV-JbS"/>
|
||||
<include reference="KIN-pk-9pP"/>
|
||||
|
@ -514,7 +518,6 @@ Lorem ipsum : Quick explanation of Fingerprints</string>
|
|||
<include reference="nEQ-Wa-OyH"/>
|
||||
<include reference="sho-vB-Yk8"/>
|
||||
<include reference="wdN-bv-bSl"/>
|
||||
<include reference="1dB-W2-GMz"/>
|
||||
</mask>
|
||||
</variation>
|
||||
</view>
|
||||
|
@ -535,10 +538,10 @@ Lorem ipsum : Quick explanation of Fingerprints</string>
|
|||
</objects>
|
||||
<point key="canvasLocation" x="3165" y="-261"/>
|
||||
</scene>
|
||||
<!--View Controller-->
|
||||
<!--Initial View Controller-->
|
||||
<scene sceneID="t5l-Kr-ojc">
|
||||
<objects>
|
||||
<viewController id="kts-vO-ui1" sceneMemberID="viewController">
|
||||
<viewController storyboardIdentifier="RegisterInitialViewController" useStoryboardIdentifierAsRestorationIdentifier="YES" id="kts-vO-ui1" customClass="InitialViewController" sceneMemberID="viewController">
|
||||
<layoutGuides>
|
||||
<viewControllerLayoutGuide type="top" id="sBS-MF-j0u"/>
|
||||
<viewControllerLayoutGuide type="bottom" id="RQS-Iz-2vV"/>
|
||||
|
@ -689,9 +692,6 @@ Lorem ipsum : Quick explanation of Fingerprints</string>
|
|||
<state key="normal" title="Okay, let's do this !">
|
||||
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</state>
|
||||
<variation key="heightClass=regular-widthClass=compact" misplaced="YES">
|
||||
<rect key="frame" x="135" y="750" width="131" height="30"/>
|
||||
</variation>
|
||||
<connections>
|
||||
<segue destination="sL4-Zw-2Og" kind="show" id="QK8-XK-Wd3"/>
|
||||
</connections>
|
||||
|
@ -747,28 +747,28 @@ Lorem ipsum : Quick explanation of Fingerprints</string>
|
|||
<exclude reference="aLd-65-HKk"/>
|
||||
<exclude reference="bng-yH-By6"/>
|
||||
<exclude reference="vyh-Rc-JYc"/>
|
||||
<exclude reference="Rvg-Br-JhL"/>
|
||||
<exclude reference="6nH-Or-yM8"/>
|
||||
<exclude reference="Awz-px-K0y"/>
|
||||
<exclude reference="oXP-v0-BQf"/>
|
||||
<exclude reference="Nhk-c5-QXU"/>
|
||||
<exclude reference="TXe-eX-lw8"/>
|
||||
<exclude reference="cmZ-ha-WzX"/>
|
||||
<exclude reference="Whv-CV-znA"/>
|
||||
<exclude reference="cLa-Bf-WM5"/>
|
||||
<exclude reference="q8l-7T-LhE"/>
|
||||
<exclude reference="hh6-UD-2pI"/>
|
||||
<exclude reference="nmJ-hM-BR1"/>
|
||||
<exclude reference="Ltq-tU-sVn"/>
|
||||
<exclude reference="Z0C-6N-HnE"/>
|
||||
<exclude reference="2LP-n6-sju"/>
|
||||
<exclude reference="7iK-MA-IkY"/>
|
||||
<exclude reference="7pm-Ag-hz5"/>
|
||||
<exclude reference="YIO-Kg-5LJ"/>
|
||||
<exclude reference="Z96-LX-bJp"/>
|
||||
<exclude reference="pXw-HR-yfM"/>
|
||||
<exclude reference="Nhk-c5-QXU"/>
|
||||
<exclude reference="TXe-eX-lw8"/>
|
||||
<exclude reference="cmZ-ha-WzX"/>
|
||||
<exclude reference="Ltq-tU-sVn"/>
|
||||
<exclude reference="Z0C-6N-HnE"/>
|
||||
<exclude reference="6nH-Or-yM8"/>
|
||||
<exclude reference="Awz-px-K0y"/>
|
||||
<exclude reference="oXP-v0-BQf"/>
|
||||
<exclude reference="GVY-Zq-Uwd"/>
|
||||
<exclude reference="nJF-Ps-cdn"/>
|
||||
<exclude reference="Whv-CV-znA"/>
|
||||
<exclude reference="cLa-Bf-WM5"/>
|
||||
<exclude reference="q8l-7T-LhE"/>
|
||||
<exclude reference="hh6-UD-2pI"/>
|
||||
<exclude reference="nmJ-hM-BR1"/>
|
||||
<exclude reference="Rvg-Br-JhL"/>
|
||||
</mask>
|
||||
</variation>
|
||||
<variation key="heightClass=regular-widthClass=compact">
|
||||
|
@ -789,35 +789,35 @@ Lorem ipsum : Quick explanation of Fingerprints</string>
|
|||
<include reference="aLd-65-HKk"/>
|
||||
<include reference="bng-yH-By6"/>
|
||||
<include reference="vyh-Rc-JYc"/>
|
||||
<include reference="Rvg-Br-JhL"/>
|
||||
<include reference="6nH-Or-yM8"/>
|
||||
<include reference="Awz-px-K0y"/>
|
||||
<include reference="oXP-v0-BQf"/>
|
||||
<include reference="Nhk-c5-QXU"/>
|
||||
<include reference="TXe-eX-lw8"/>
|
||||
<include reference="cmZ-ha-WzX"/>
|
||||
<include reference="Whv-CV-znA"/>
|
||||
<include reference="cLa-Bf-WM5"/>
|
||||
<include reference="q8l-7T-LhE"/>
|
||||
<include reference="hh6-UD-2pI"/>
|
||||
<exclude reference="nmJ-hM-BR1"/>
|
||||
<include reference="Ltq-tU-sVn"/>
|
||||
<include reference="Z0C-6N-HnE"/>
|
||||
<include reference="2LP-n6-sju"/>
|
||||
<include reference="7iK-MA-IkY"/>
|
||||
<include reference="7pm-Ag-hz5"/>
|
||||
<include reference="YIO-Kg-5LJ"/>
|
||||
<include reference="Z96-LX-bJp"/>
|
||||
<include reference="pXw-HR-yfM"/>
|
||||
<include reference="Nhk-c5-QXU"/>
|
||||
<include reference="TXe-eX-lw8"/>
|
||||
<include reference="cmZ-ha-WzX"/>
|
||||
<include reference="Ltq-tU-sVn"/>
|
||||
<include reference="Z0C-6N-HnE"/>
|
||||
<include reference="6nH-Or-yM8"/>
|
||||
<include reference="Awz-px-K0y"/>
|
||||
<include reference="oXP-v0-BQf"/>
|
||||
<include reference="GVY-Zq-Uwd"/>
|
||||
<include reference="nJF-Ps-cdn"/>
|
||||
<include reference="Whv-CV-znA"/>
|
||||
<include reference="cLa-Bf-WM5"/>
|
||||
<include reference="q8l-7T-LhE"/>
|
||||
<include reference="hh6-UD-2pI"/>
|
||||
<exclude reference="nmJ-hM-BR1"/>
|
||||
<include reference="Rvg-Br-JhL"/>
|
||||
</mask>
|
||||
</variation>
|
||||
</view>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="m6j-Wp-Kgl" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="-2751" y="62.25"/>
|
||||
<point key="canvasLocation" x="-2856" y="62.25"/>
|
||||
</scene>
|
||||
<!--Registration View Controller-->
|
||||
<scene sceneID="okO-46-HuB">
|
||||
|
@ -1073,36 +1073,36 @@ Lorem ipsum : Quick explanation of Fingerprints</string>
|
|||
<exclude reference="qJb-ZJ-J5r"/>
|
||||
</mask>
|
||||
<mask key="constraints">
|
||||
<exclude reference="MVu-wT-IQ7"/>
|
||||
<exclude reference="g1b-ej-0d4"/>
|
||||
<exclude reference="hKi-GO-2of"/>
|
||||
<exclude reference="5f6-02-b9v"/>
|
||||
<exclude reference="Hse-EY-vcs"/>
|
||||
<exclude reference="cRf-MG-bzv"/>
|
||||
<exclude reference="p3l-YS-pks"/>
|
||||
<exclude reference="Cbx-OD-VBj"/>
|
||||
<exclude reference="EW6-BX-FsU"/>
|
||||
<exclude reference="ubP-u6-1GA"/>
|
||||
<exclude reference="LBA-XZ-pRF"/>
|
||||
<exclude reference="Eaa-Ad-hwk"/>
|
||||
<exclude reference="J4b-jA-oSj"/>
|
||||
<exclude reference="fsb-fW-aTG"/>
|
||||
<exclude reference="kWH-oD-5Hw"/>
|
||||
<exclude reference="MVu-wT-IQ7"/>
|
||||
<exclude reference="g1b-ej-0d4"/>
|
||||
<exclude reference="hKi-GO-2of"/>
|
||||
<exclude reference="Api-xm-ASa"/>
|
||||
<exclude reference="MSP-yX-DrP"/>
|
||||
<exclude reference="mYi-az-aVL"/>
|
||||
<exclude reference="EJb-70-lg4"/>
|
||||
<exclude reference="LHc-pG-ofW"/>
|
||||
<exclude reference="PFH-fV-jvN"/>
|
||||
<exclude reference="TUP-Kq-afk"/>
|
||||
<exclude reference="V1z-yH-GJt"/>
|
||||
<exclude reference="ih2-I3-eGH"/>
|
||||
<exclude reference="89J-Z1-TDD"/>
|
||||
<exclude reference="cz5-NL-Bmw"/>
|
||||
<exclude reference="Api-xm-ASa"/>
|
||||
<exclude reference="MSP-yX-DrP"/>
|
||||
<exclude reference="mYi-az-aVL"/>
|
||||
<exclude reference="Lmj-kn-XPR"/>
|
||||
<exclude reference="EJb-70-lg4"/>
|
||||
<exclude reference="LHc-pG-ofW"/>
|
||||
<exclude reference="PFH-fV-jvN"/>
|
||||
<exclude reference="SfR-rA-lmN"/>
|
||||
<exclude reference="ab0-TM-8nb"/>
|
||||
<exclude reference="oPp-yY-WZN"/>
|
||||
<exclude reference="Cbx-OD-VBj"/>
|
||||
<exclude reference="EW6-BX-FsU"/>
|
||||
<exclude reference="ubP-u6-1GA"/>
|
||||
<exclude reference="89J-Z1-TDD"/>
|
||||
<exclude reference="cz5-NL-Bmw"/>
|
||||
<exclude reference="Lmj-kn-XPR"/>
|
||||
<exclude reference="LBA-XZ-pRF"/>
|
||||
</mask>
|
||||
</variation>
|
||||
<variation key="heightClass=regular-widthClass=compact">
|
||||
|
@ -1119,36 +1119,36 @@ Lorem ipsum : Quick explanation of Fingerprints</string>
|
|||
<include reference="qJb-ZJ-J5r"/>
|
||||
</mask>
|
||||
<mask key="constraints">
|
||||
<include reference="MVu-wT-IQ7"/>
|
||||
<include reference="g1b-ej-0d4"/>
|
||||
<include reference="hKi-GO-2of"/>
|
||||
<include reference="5f6-02-b9v"/>
|
||||
<include reference="Hse-EY-vcs"/>
|
||||
<include reference="cRf-MG-bzv"/>
|
||||
<include reference="p3l-YS-pks"/>
|
||||
<include reference="Cbx-OD-VBj"/>
|
||||
<include reference="EW6-BX-FsU"/>
|
||||
<include reference="ubP-u6-1GA"/>
|
||||
<include reference="LBA-XZ-pRF"/>
|
||||
<include reference="Eaa-Ad-hwk"/>
|
||||
<include reference="J4b-jA-oSj"/>
|
||||
<include reference="fsb-fW-aTG"/>
|
||||
<include reference="kWH-oD-5Hw"/>
|
||||
<include reference="MVu-wT-IQ7"/>
|
||||
<include reference="g1b-ej-0d4"/>
|
||||
<include reference="hKi-GO-2of"/>
|
||||
<include reference="Api-xm-ASa"/>
|
||||
<include reference="MSP-yX-DrP"/>
|
||||
<include reference="mYi-az-aVL"/>
|
||||
<include reference="EJb-70-lg4"/>
|
||||
<include reference="LHc-pG-ofW"/>
|
||||
<include reference="PFH-fV-jvN"/>
|
||||
<include reference="TUP-Kq-afk"/>
|
||||
<include reference="V1z-yH-GJt"/>
|
||||
<include reference="ih2-I3-eGH"/>
|
||||
<include reference="89J-Z1-TDD"/>
|
||||
<include reference="cz5-NL-Bmw"/>
|
||||
<include reference="Api-xm-ASa"/>
|
||||
<include reference="MSP-yX-DrP"/>
|
||||
<include reference="mYi-az-aVL"/>
|
||||
<include reference="Lmj-kn-XPR"/>
|
||||
<include reference="EJb-70-lg4"/>
|
||||
<include reference="LHc-pG-ofW"/>
|
||||
<include reference="PFH-fV-jvN"/>
|
||||
<include reference="SfR-rA-lmN"/>
|
||||
<include reference="ab0-TM-8nb"/>
|
||||
<include reference="oPp-yY-WZN"/>
|
||||
<include reference="Cbx-OD-VBj"/>
|
||||
<include reference="EW6-BX-FsU"/>
|
||||
<include reference="ubP-u6-1GA"/>
|
||||
<include reference="89J-Z1-TDD"/>
|
||||
<include reference="cz5-NL-Bmw"/>
|
||||
<include reference="Lmj-kn-XPR"/>
|
||||
<include reference="LBA-XZ-pRF"/>
|
||||
</mask>
|
||||
</variation>
|
||||
</view>
|
||||
|
@ -1270,14 +1270,14 @@ Lorem ipsum : Quick explanation of Fingerprints</string>
|
|||
</state>
|
||||
<variation key="default">
|
||||
<mask key="constraints">
|
||||
<exclude reference="lfU-Qy-gcH"/>
|
||||
<exclude reference="Ruw-po-bob"/>
|
||||
<exclude reference="lfU-Qy-gcH"/>
|
||||
</mask>
|
||||
</variation>
|
||||
<variation key="heightClass=regular-widthClass=compact">
|
||||
<mask key="constraints">
|
||||
<include reference="lfU-Qy-gcH"/>
|
||||
<include reference="Ruw-po-bob"/>
|
||||
<include reference="lfU-Qy-gcH"/>
|
||||
</mask>
|
||||
</variation>
|
||||
<connections>
|
||||
|
@ -1345,20 +1345,20 @@ Lorem ipsum : Quick explanation of Fingerprints</string>
|
|||
<exclude reference="JFF-KZ-h6I"/>
|
||||
<exclude reference="dP3-9o-eNP"/>
|
||||
<exclude reference="oSp-IH-lVa"/>
|
||||
<exclude reference="J0Z-pe-1GZ"/>
|
||||
<exclude reference="oPh-8d-yYT"/>
|
||||
<exclude reference="StQ-SP-FMd"/>
|
||||
<exclude reference="AIw-5F-Lfj"/>
|
||||
<exclude reference="LsW-Pq-PRZ"/>
|
||||
<exclude reference="c47-uE-awH"/>
|
||||
<exclude reference="yuF-1t-XeW"/>
|
||||
<exclude reference="J0Z-pe-1GZ"/>
|
||||
<exclude reference="oPh-8d-yYT"/>
|
||||
<exclude reference="rmZ-rb-JoP"/>
|
||||
<exclude reference="9hL-iF-RZL"/>
|
||||
<exclude reference="M8V-ht-k2s"/>
|
||||
<exclude reference="Mb0-Wd-GVx"/>
|
||||
<exclude reference="dvC-Xu-1F4"/>
|
||||
<exclude reference="mNE-hX-tgd"/>
|
||||
<exclude reference="z0p-1R-W5Z"/>
|
||||
<exclude reference="9hL-iF-RZL"/>
|
||||
<exclude reference="M8V-ht-k2s"/>
|
||||
<exclude reference="rmZ-rb-JoP"/>
|
||||
<exclude reference="StQ-SP-FMd"/>
|
||||
</mask>
|
||||
</variation>
|
||||
<variation key="heightClass=regular-widthClass=compact">
|
||||
|
@ -1375,20 +1375,20 @@ Lorem ipsum : Quick explanation of Fingerprints</string>
|
|||
<include reference="JFF-KZ-h6I"/>
|
||||
<include reference="dP3-9o-eNP"/>
|
||||
<include reference="oSp-IH-lVa"/>
|
||||
<include reference="J0Z-pe-1GZ"/>
|
||||
<include reference="oPh-8d-yYT"/>
|
||||
<include reference="StQ-SP-FMd"/>
|
||||
<include reference="AIw-5F-Lfj"/>
|
||||
<include reference="LsW-Pq-PRZ"/>
|
||||
<include reference="c47-uE-awH"/>
|
||||
<include reference="yuF-1t-XeW"/>
|
||||
<include reference="J0Z-pe-1GZ"/>
|
||||
<include reference="oPh-8d-yYT"/>
|
||||
<include reference="rmZ-rb-JoP"/>
|
||||
<include reference="9hL-iF-RZL"/>
|
||||
<include reference="M8V-ht-k2s"/>
|
||||
<include reference="Mb0-Wd-GVx"/>
|
||||
<include reference="dvC-Xu-1F4"/>
|
||||
<include reference="mNE-hX-tgd"/>
|
||||
<include reference="z0p-1R-W5Z"/>
|
||||
<include reference="9hL-iF-RZL"/>
|
||||
<include reference="M8V-ht-k2s"/>
|
||||
<include reference="rmZ-rb-JoP"/>
|
||||
<include reference="StQ-SP-FMd"/>
|
||||
</mask>
|
||||
</variation>
|
||||
</view>
|
||||
|
@ -1404,7 +1404,7 @@ Lorem ipsum : Quick explanation of Fingerprints</string>
|
|||
<!--Tab Bar Controller-->
|
||||
<scene sceneID="dB1-7w-8YS">
|
||||
<objects>
|
||||
<tabBarController id="QKN-cj-wuH" sceneMemberID="viewController">
|
||||
<tabBarController storyboardIdentifier="UserInitialViewController" useStoryboardIdentifierAsRestorationIdentifier="YES" id="QKN-cj-wuH" sceneMemberID="viewController">
|
||||
<nil key="simulatedBottomBarMetrics"/>
|
||||
<tabBar key="tabBar" contentMode="scaleToFill" translucent="NO" id="JT6-cn-7qk">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="49"/>
|
||||
|
@ -1428,7 +1428,7 @@ Lorem ipsum : Quick explanation of Fingerprints</string>
|
|||
<objects>
|
||||
<tableViewController id="6mY-1Q-YBT" customClass="ContactsTableViewController" sceneMemberID="viewController">
|
||||
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" showsHorizontalScrollIndicator="NO" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="22" sectionFooterHeight="22" id="GqA-oC-CJa">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="551"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<connections>
|
||||
|
@ -1456,7 +1456,7 @@ Lorem ipsum : Quick explanation of Fingerprints</string>
|
|||
<objects>
|
||||
<tableViewController id="0XE-hu-8cu" customClass="ContactDetailTableViewController" sceneMemberID="viewController">
|
||||
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" dataMode="prototypes" style="plain" separatorStyle="default" showsSelectionImmediatelyOnTouchBegin="NO" rowHeight="150" sectionHeaderHeight="22" sectionFooterHeight="22" id="RoU-YO-d5P">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="551"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" red="0.94901960780000005" green="0.94901960780000005" blue="0.94901960780000005" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<inset key="separatorInset" minX="0.0" minY="0.0" maxX="0.0" maxY="0.0"/>
|
||||
|
@ -1804,14 +1804,14 @@ Lorem ipsum : Quick explanation of Fingerprints</string>
|
|||
</constraints>
|
||||
<variation key="default">
|
||||
<mask key="constraints">
|
||||
<exclude reference="Okl-6f-L17"/>
|
||||
<exclude reference="Lz7-10-swg"/>
|
||||
<exclude reference="Okl-6f-L17"/>
|
||||
</mask>
|
||||
</variation>
|
||||
<variation key="heightClass=regular-widthClass=compact">
|
||||
<mask key="constraints">
|
||||
<exclude reference="Okl-6f-L17"/>
|
||||
<exclude reference="Lz7-10-swg"/>
|
||||
<exclude reference="Okl-6f-L17"/>
|
||||
</mask>
|
||||
</variation>
|
||||
</view>
|
||||
|
@ -1884,51 +1884,51 @@ Lorem ipsum : Quick explanation of Fingerprints</string>
|
|||
<exclude reference="Zsn-j2-iss"/>
|
||||
</mask>
|
||||
<mask key="constraints">
|
||||
<exclude reference="CzT-yE-ZZi"/>
|
||||
<exclude reference="flS-Xw-75h"/>
|
||||
<exclude reference="jGu-1E-j8M"/>
|
||||
<exclude reference="jyc-n8-PKc"/>
|
||||
<exclude reference="zEd-WD-12z"/>
|
||||
<exclude reference="21j-rl-WRG"/>
|
||||
<exclude reference="lfC-an-3PO"/>
|
||||
<exclude reference="s21-7m-4p1"/>
|
||||
<exclude reference="GLu-P7-34J"/>
|
||||
<exclude reference="t1A-Xg-gyG"/>
|
||||
<exclude reference="BJb-Ry-zyX"/>
|
||||
<exclude reference="UAY-g9-QYx"/>
|
||||
<exclude reference="hI0-P4-36D"/>
|
||||
<exclude reference="qul-nY-DWw"/>
|
||||
<exclude reference="Djf-iL-emf"/>
|
||||
<exclude reference="Kmg-X8-OTM"/>
|
||||
<exclude reference="VZj-eb-IRz"/>
|
||||
<exclude reference="lsu-rO-VMN"/>
|
||||
<exclude reference="C9w-qG-yIC"/>
|
||||
<exclude reference="KD5-FZ-hIh"/>
|
||||
<exclude reference="nYa-Xr-g5M"/>
|
||||
<exclude reference="toZ-zh-Iy3"/>
|
||||
<exclude reference="uMB-bd-99x"/>
|
||||
<exclude reference="5uk-1r-gO8"/>
|
||||
<exclude reference="AYa-13-Olz"/>
|
||||
<exclude reference="o3e-xc-rMx"/>
|
||||
<exclude reference="oW3-SC-n5d"/>
|
||||
<exclude reference="Dfd-BI-EVU"/>
|
||||
<exclude reference="EbC-OA-toO"/>
|
||||
<exclude reference="KBe-Kz-PLK"/>
|
||||
<exclude reference="roy-5R-k37"/>
|
||||
<exclude reference="GLu-P7-34J"/>
|
||||
<exclude reference="t1A-Xg-gyG"/>
|
||||
<exclude reference="H6U-fc-9b2"/>
|
||||
<exclude reference="gq2-cU-hxB"/>
|
||||
<exclude reference="xSY-Mj-hsV"/>
|
||||
<exclude reference="LbB-cI-KRS"/>
|
||||
<exclude reference="dXh-Ni-5ir"/>
|
||||
<exclude reference="h8G-EJ-HRu"/>
|
||||
<exclude reference="jUC-ks-oP9"/>
|
||||
<exclude reference="rzX-gG-TUg"/>
|
||||
<exclude reference="u2o-ze-nBj"/>
|
||||
<exclude reference="C9w-qG-yIC"/>
|
||||
<exclude reference="KD5-FZ-hIh"/>
|
||||
<exclude reference="nYa-Xr-g5M"/>
|
||||
<exclude reference="toZ-zh-Iy3"/>
|
||||
<exclude reference="uMB-bd-99x"/>
|
||||
<exclude reference="H6U-fc-9b2"/>
|
||||
<exclude reference="gq2-cU-hxB"/>
|
||||
<exclude reference="xSY-Mj-hsV"/>
|
||||
<exclude reference="3hj-H8-HfI"/>
|
||||
<exclude reference="KYD-g0-SgI"/>
|
||||
<exclude reference="SSa-0O-Ps6"/>
|
||||
<exclude reference="rKw-Rl-kDD"/>
|
||||
<exclude reference="sLh-9u-amX"/>
|
||||
<exclude reference="CzT-yE-ZZi"/>
|
||||
<exclude reference="flS-Xw-75h"/>
|
||||
<exclude reference="jGu-1E-j8M"/>
|
||||
<exclude reference="jyc-n8-PKc"/>
|
||||
<exclude reference="zEd-WD-12z"/>
|
||||
<exclude reference="Dfd-BI-EVU"/>
|
||||
<exclude reference="EbC-OA-toO"/>
|
||||
<exclude reference="KBe-Kz-PLK"/>
|
||||
<exclude reference="roy-5R-k37"/>
|
||||
<exclude reference="BJb-Ry-zyX"/>
|
||||
<exclude reference="UAY-g9-QYx"/>
|
||||
<exclude reference="hI0-P4-36D"/>
|
||||
<exclude reference="qul-nY-DWw"/>
|
||||
</mask>
|
||||
</variation>
|
||||
<variation key="heightClass=regular-widthClass=compact">
|
||||
|
@ -1946,51 +1946,51 @@ Lorem ipsum : Quick explanation of Fingerprints</string>
|
|||
<include reference="Zsn-j2-iss"/>
|
||||
</mask>
|
||||
<mask key="constraints">
|
||||
<include reference="CzT-yE-ZZi"/>
|
||||
<exclude reference="flS-Xw-75h"/>
|
||||
<include reference="jGu-1E-j8M"/>
|
||||
<include reference="jyc-n8-PKc"/>
|
||||
<include reference="zEd-WD-12z"/>
|
||||
<include reference="21j-rl-WRG"/>
|
||||
<include reference="lfC-an-3PO"/>
|
||||
<include reference="s21-7m-4p1"/>
|
||||
<include reference="GLu-P7-34J"/>
|
||||
<include reference="t1A-Xg-gyG"/>
|
||||
<include reference="BJb-Ry-zyX"/>
|
||||
<include reference="UAY-g9-QYx"/>
|
||||
<include reference="hI0-P4-36D"/>
|
||||
<include reference="qul-nY-DWw"/>
|
||||
<include reference="Djf-iL-emf"/>
|
||||
<exclude reference="Kmg-X8-OTM"/>
|
||||
<include reference="VZj-eb-IRz"/>
|
||||
<include reference="lsu-rO-VMN"/>
|
||||
<include reference="C9w-qG-yIC"/>
|
||||
<exclude reference="KD5-FZ-hIh"/>
|
||||
<include reference="nYa-Xr-g5M"/>
|
||||
<include reference="toZ-zh-Iy3"/>
|
||||
<include reference="uMB-bd-99x"/>
|
||||
<include reference="5uk-1r-gO8"/>
|
||||
<include reference="AYa-13-Olz"/>
|
||||
<exclude reference="o3e-xc-rMx"/>
|
||||
<include reference="oW3-SC-n5d"/>
|
||||
<include reference="Dfd-BI-EVU"/>
|
||||
<include reference="EbC-OA-toO"/>
|
||||
<include reference="KBe-Kz-PLK"/>
|
||||
<exclude reference="roy-5R-k37"/>
|
||||
<include reference="GLu-P7-34J"/>
|
||||
<include reference="t1A-Xg-gyG"/>
|
||||
<exclude reference="H6U-fc-9b2"/>
|
||||
<include reference="gq2-cU-hxB"/>
|
||||
<include reference="xSY-Mj-hsV"/>
|
||||
<include reference="LbB-cI-KRS"/>
|
||||
<include reference="dXh-Ni-5ir"/>
|
||||
<include reference="h8G-EJ-HRu"/>
|
||||
<include reference="jUC-ks-oP9"/>
|
||||
<include reference="rzX-gG-TUg"/>
|
||||
<include reference="u2o-ze-nBj"/>
|
||||
<include reference="C9w-qG-yIC"/>
|
||||
<exclude reference="KD5-FZ-hIh"/>
|
||||
<include reference="nYa-Xr-g5M"/>
|
||||
<include reference="toZ-zh-Iy3"/>
|
||||
<include reference="uMB-bd-99x"/>
|
||||
<exclude reference="H6U-fc-9b2"/>
|
||||
<include reference="gq2-cU-hxB"/>
|
||||
<include reference="xSY-Mj-hsV"/>
|
||||
<include reference="3hj-H8-HfI"/>
|
||||
<include reference="KYD-g0-SgI"/>
|
||||
<include reference="SSa-0O-Ps6"/>
|
||||
<include reference="rKw-Rl-kDD"/>
|
||||
<include reference="sLh-9u-amX"/>
|
||||
<include reference="CzT-yE-ZZi"/>
|
||||
<exclude reference="flS-Xw-75h"/>
|
||||
<include reference="jGu-1E-j8M"/>
|
||||
<include reference="jyc-n8-PKc"/>
|
||||
<include reference="zEd-WD-12z"/>
|
||||
<include reference="Dfd-BI-EVU"/>
|
||||
<include reference="EbC-OA-toO"/>
|
||||
<include reference="KBe-Kz-PLK"/>
|
||||
<exclude reference="roy-5R-k37"/>
|
||||
<include reference="BJb-Ry-zyX"/>
|
||||
<include reference="UAY-g9-QYx"/>
|
||||
<include reference="hI0-P4-36D"/>
|
||||
<include reference="qul-nY-DWw"/>
|
||||
</mask>
|
||||
</variation>
|
||||
</tableViewCellContentView>
|
||||
|
@ -2435,11 +2435,11 @@ Lorem ipsum : Quick explanation of Fingerprints</string>
|
|||
<objects>
|
||||
<tableViewController id="n1f-7Y-906" customClass="SettingsTableViewController" sceneMemberID="viewController">
|
||||
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="static" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="22" sectionFooterHeight="22" id="FhQ-dM-1mj">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="551"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" red="0.94901960780000005" green="0.94901960780000005" blue="0.94901960780000005" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<view key="tableFooterView" contentMode="scaleToFill" id="Ezq-Cw-na2">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="568"/>
|
||||
<rect key="frame" x="0.0" y="600" width="600" height="568"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="2" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="yD5-2a-WDn">
|
||||
|
@ -2449,6 +2449,9 @@ Licensed under the GPLv3</string>
|
|||
<fontDescription key="fontDescription" type="system" pointSize="11"/>
|
||||
<color key="textColor" white="0.66666666666666663" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<nil key="highlightedColor"/>
|
||||
<variation key="heightClass=regular-widthClass=compact" misplaced="YES">
|
||||
<rect key="frame" x="8" y="8" width="584" height="552"/>
|
||||
</variation>
|
||||
</label>
|
||||
</subviews>
|
||||
<color key="backgroundColor" red="0.94901960780000005" green="0.94901960780000005" blue="0.94901960780000005" alpha="1" colorSpace="calibratedRGB"/>
|
||||
|
@ -2586,6 +2589,9 @@ Licensed under the GPLv3</string>
|
|||
<exclude reference="4cA-kW-n9A"/>
|
||||
<exclude reference="5bY-hD-EYS"/>
|
||||
<exclude reference="gVJ-kJ-ilB"/>
|
||||
<exclude reference="c5a-HY-X68"/>
|
||||
<exclude reference="cU4-H3-udB"/>
|
||||
<exclude reference="nIo-TW-c0a"/>
|
||||
<exclude reference="NBK-Mf-MTg"/>
|
||||
<exclude reference="R9V-av-5jf"/>
|
||||
<exclude reference="RFM-q7-ucC"/>
|
||||
|
@ -2593,9 +2599,6 @@ Licensed under the GPLv3</string>
|
|||
<exclude reference="oNo-wq-biP"/>
|
||||
<exclude reference="pmi-gE-xSY"/>
|
||||
<exclude reference="xnt-2P-MDu"/>
|
||||
<exclude reference="c5a-HY-X68"/>
|
||||
<exclude reference="cU4-H3-udB"/>
|
||||
<exclude reference="nIo-TW-c0a"/>
|
||||
</mask>
|
||||
</variation>
|
||||
<variation key="heightClass=regular-widthClass=compact">
|
||||
|
@ -2609,6 +2612,9 @@ Licensed under the GPLv3</string>
|
|||
<include reference="4cA-kW-n9A"/>
|
||||
<include reference="5bY-hD-EYS"/>
|
||||
<include reference="gVJ-kJ-ilB"/>
|
||||
<include reference="c5a-HY-X68"/>
|
||||
<include reference="cU4-H3-udB"/>
|
||||
<include reference="nIo-TW-c0a"/>
|
||||
<include reference="NBK-Mf-MTg"/>
|
||||
<include reference="R9V-av-5jf"/>
|
||||
<include reference="RFM-q7-ucC"/>
|
||||
|
@ -2616,9 +2622,6 @@ Licensed under the GPLv3</string>
|
|||
<exclude reference="oNo-wq-biP"/>
|
||||
<include reference="pmi-gE-xSY"/>
|
||||
<include reference="xnt-2P-MDu"/>
|
||||
<include reference="c5a-HY-X68"/>
|
||||
<include reference="cU4-H3-udB"/>
|
||||
<include reference="nIo-TW-c0a"/>
|
||||
</mask>
|
||||
</variation>
|
||||
</tableViewCellContentView>
|
||||
|
@ -3338,7 +3341,8 @@ Licensed under the GPLv3</string>
|
|||
<exclude reference="ZIm-Uq-bM8"/>
|
||||
</mask>
|
||||
</variation>
|
||||
<variation key="heightClass=regular-widthClass=compact">
|
||||
<variation key="heightClass=regular-widthClass=compact" misplaced="YES">
|
||||
<rect key="frame" x="0.0" y="20" width="400" height="100"/>
|
||||
<mask key="subviews">
|
||||
<include reference="Ul8-NY-i4c"/>
|
||||
<include reference="gbm-B5-gCc"/>
|
||||
|
@ -3392,6 +3396,9 @@ Licensed under the GPLv3</string>
|
|||
</tableViewCellContentView>
|
||||
</tableViewCell>
|
||||
</prototypes>
|
||||
<variation key="heightClass=regular-widthClass=compact" misplaced="YES">
|
||||
<rect key="frame" x="0.0" y="128" width="400" height="672"/>
|
||||
</variation>
|
||||
<connections>
|
||||
<outlet property="dataSource" destination="bDi-2Q-XOC" id="VPO-ms-bH1"/>
|
||||
<outlet property="delegate" destination="bDi-2Q-XOC" id="rKM-jX-C39"/>
|
||||
|
@ -3476,6 +3483,6 @@ Licensed under the GPLv3</string>
|
|||
<image name="signals.png" width="24" height="24"/>
|
||||
</resources>
|
||||
<inferredMetricsTieBreakers>
|
||||
<segue reference="qCk-gl-KCX"/>
|
||||
<segue reference="QK8-XK-Wd3"/>
|
||||
</inferredMetricsTieBreakers>
|
||||
</document>
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#import <Foundation/Foundation.h>
|
||||
#import "PhoneNumberDirectoryFilter.h"
|
||||
#import "PropertyListPreferences.h"
|
||||
#import "CallLogViewController.h"
|
||||
#import "Zid.h"
|
||||
|
||||
@class PhoneNumber;
|
||||
|
|
|
@ -58,22 +58,12 @@
|
|||
return;
|
||||
}
|
||||
|
||||
if (SYSTEM_VERSION_LESS_THAN(_iOS_8_0)) {
|
||||
|
||||
// On iOS7, we just need to register for Push Notifications (user notifications are enabled with them)
|
||||
[self registrationForPushWithSuccess:success failure:failure];
|
||||
|
||||
} else{
|
||||
|
||||
// On iOS 8+, both Push Notifications and User Notfications need to be registered.
|
||||
|
||||
[self registrationForPushWithSuccess:^{
|
||||
[self registrationForUserNotificationWithSuccess:success failure:^{
|
||||
[self.missingPermissionsAlertView show];
|
||||
failure();
|
||||
}];
|
||||
} failure:failure];
|
||||
}
|
||||
[self registrationForPushWithSuccess:^{
|
||||
[self registrationForUserNotificationWithSuccess:success failure:^{
|
||||
[self.missingPermissionsAlertView show];
|
||||
failure();
|
||||
}];
|
||||
} failure:failure];
|
||||
}
|
||||
|
||||
|
||||
|
@ -108,15 +98,8 @@
|
|||
|
||||
-(TOCFuture*)registerPushNotificationFuture{
|
||||
self.pushNotificationFutureSource = [TOCFutureSource new];
|
||||
[UIApplication.sharedApplication registerForRemoteNotifications];
|
||||
|
||||
if (SYSTEM_VERSION_LESS_THAN(_iOS_8_0)) {
|
||||
[UIApplication.sharedApplication registerForRemoteNotificationTypes:(UIRemoteNotificationType)self.mandatoryNotificationTypes];
|
||||
if ([self isMissingMandatoryNotificationTypes]) {
|
||||
[self.pushNotificationFutureSource trySetFailure:@"Missing Types"];
|
||||
}
|
||||
} else {
|
||||
[UIApplication.sharedApplication registerForRemoteNotifications];
|
||||
}
|
||||
return self.pushNotificationFutureSource.future;
|
||||
}
|
||||
|
||||
|
@ -173,11 +156,7 @@
|
|||
}
|
||||
|
||||
-(BOOL) needToRegisterForRemoteNotifications {
|
||||
if (SYSTEM_VERSION_LESS_THAN(_iOS_8_0)) {
|
||||
return self.wantRemoteNotifications;
|
||||
} else{
|
||||
return self.wantRemoteNotifications && (!UIApplication.sharedApplication.isRegisteredForRemoteNotifications);
|
||||
}
|
||||
return self.wantRemoteNotifications && (!UIApplication.sharedApplication.isRegisteredForRemoteNotifications);
|
||||
}
|
||||
|
||||
-(BOOL) wantRemoteNotifications {
|
||||
|
@ -216,29 +195,17 @@
|
|||
|
||||
-(BOOL)isMissingMandatoryNotificationTypes {
|
||||
int mandatoryTypes = self.mandatoryNotificationTypes;
|
||||
int currentTypes;
|
||||
if (SYSTEM_VERSION_LESS_THAN(_iOS_8_0)) {
|
||||
currentTypes = UIApplication.sharedApplication.enabledRemoteNotificationTypes;
|
||||
} else {
|
||||
currentTypes = UIApplication.sharedApplication.currentUserNotificationSettings.types;
|
||||
}
|
||||
int currentTypes = UIApplication.sharedApplication.currentUserNotificationSettings.types;
|
||||
|
||||
return (mandatoryTypes & currentTypes) != mandatoryTypes;
|
||||
}
|
||||
|
||||
-(int)allNotificationTypes{
|
||||
if (SYSTEM_VERSION_LESS_THAN(_iOS_8_0)) {
|
||||
return UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeBadge;
|
||||
} else {
|
||||
return UIUserNotificationTypeAlert | UIUserNotificationTypeSound | UIUserNotificationTypeBadge;
|
||||
}
|
||||
return UIUserNotificationTypeAlert | UIUserNotificationTypeSound | UIUserNotificationTypeBadge;
|
||||
}
|
||||
|
||||
-(int)mandatoryNotificationTypes{
|
||||
if (SYSTEM_VERSION_LESS_THAN(_iOS_8_0)) {
|
||||
return UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound;
|
||||
} else {
|
||||
return UIUserNotificationTypeAlert | UIUserNotificationTypeSound;
|
||||
}
|
||||
return UIUserNotificationTypeAlert | UIUserNotificationTypeSound;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -37,12 +37,12 @@ MacrosSingletonImplemention
|
|||
NSURLSessionConfiguration *sessionConf = NSURLSessionConfiguration.ephemeralSessionConfiguration;
|
||||
self.operationManager = [[AFHTTPSessionManager alloc] initWithBaseURL:endPointURL sessionConfiguration:sessionConf];
|
||||
self.operationManager.responseSerializer = [AFJSONResponseSerializer serializer];
|
||||
self.operationManager.securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];
|
||||
self.operationManager.securityPolicy.allowInvalidCertificates = YES;
|
||||
NSString *certPath = [NSBundle.mainBundle pathForResource:@"whisperReal" ofType:@"cer"];
|
||||
NSData *certData = [NSData dataWithContentsOfFile:certPath];
|
||||
SecCertificateRef cert = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)(certData));
|
||||
self.operationManager.securityPolicy.pinnedCertificates = @[(__bridge_transfer NSData *)SecCertificateCopyData(cert)];
|
||||
self.operationManager.securityPolicy.SSLPinningMode = AFSSLPinningModeCertificate;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
|
|
@ -2,8 +2,22 @@
|
|||
|
||||
#import "ProtocolBuffers.h"
|
||||
|
||||
// @@protoc_insertion_point(imports)
|
||||
|
||||
@class InitiateSignal;
|
||||
@class InitiateSignal_Builder;
|
||||
@class InitiateSignalBuilder;
|
||||
#ifndef __has_feature
|
||||
#define __has_feature(x) 0 // Compatibility with non-clang compilers.
|
||||
#endif // __has_feature
|
||||
|
||||
#ifndef NS_RETURNS_NOT_RETAINED
|
||||
#if __has_feature(attribute_ns_returns_not_retained)
|
||||
#define NS_RETURNS_NOT_RETAINED __attribute__((ns_returns_not_retained))
|
||||
#else
|
||||
#define NS_RETURNS_NOT_RETAINED
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
@interface InitiateSignalRoot : NSObject {
|
||||
}
|
||||
|
@ -18,31 +32,32 @@
|
|||
BOOL hasServerName_:1;
|
||||
BOOL hasPort_:1;
|
||||
BOOL hasVersion_:1;
|
||||
int64_t sessionId;
|
||||
UInt64 sessionId;
|
||||
NSString* initiator;
|
||||
NSString* serverName;
|
||||
int32_t port;
|
||||
int32_t version;
|
||||
UInt32 port;
|
||||
UInt32 version;
|
||||
}
|
||||
- (BOOL) hasInitiator;
|
||||
- (BOOL) hasSessionId;
|
||||
- (BOOL) hasPort;
|
||||
- (BOOL) hasServerName;
|
||||
- (BOOL) hasVersion;
|
||||
@property (readonly, retain) NSString* initiator;
|
||||
@property (readonly) int64_t sessionId;
|
||||
@property (readonly) int32_t port;
|
||||
@property (readonly, retain) NSString* serverName;
|
||||
@property (readonly) int32_t version;
|
||||
@property (readonly, strong) NSString* initiator;
|
||||
@property (readonly) UInt64 sessionId;
|
||||
@property (readonly) UInt32 port;
|
||||
@property (readonly, strong) NSString* serverName;
|
||||
@property (readonly) UInt32 version;
|
||||
|
||||
+ (InitiateSignal*) defaultInstance;
|
||||
- (InitiateSignal*) defaultInstance;
|
||||
|
||||
- (BOOL) isInitialized;
|
||||
- (void) writeToCodedOutputStream:(PBCodedOutputStream*) output;
|
||||
- (InitiateSignal_Builder*) builder;
|
||||
+ (InitiateSignal_Builder*) builder;
|
||||
+ (InitiateSignal_Builder*) builderWithPrototype:(InitiateSignal*) prototype;
|
||||
- (InitiateSignalBuilder*) builder;
|
||||
+ (InitiateSignalBuilder*) builder;
|
||||
+ (InitiateSignalBuilder*) builderWithPrototype:(InitiateSignal*) prototype;
|
||||
- (InitiateSignalBuilder*) toBuilder;
|
||||
|
||||
+ (InitiateSignal*) parseFromData:(NSData*) data;
|
||||
+ (InitiateSignal*) parseFromData:(NSData*) data extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
|
||||
|
@ -52,46 +67,48 @@
|
|||
+ (InitiateSignal*) parseFromCodedInputStream:(PBCodedInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
|
||||
@end
|
||||
|
||||
@interface InitiateSignal_Builder : PBGeneratedMessage_Builder {
|
||||
@interface InitiateSignalBuilder : PBGeneratedMessageBuilder {
|
||||
@private
|
||||
InitiateSignal* result;
|
||||
}
|
||||
|
||||
- (InitiateSignal*) defaultInstance;
|
||||
|
||||
- (InitiateSignal_Builder*) clear;
|
||||
- (InitiateSignal_Builder*) clone;
|
||||
- (InitiateSignalBuilder*) clear;
|
||||
- (InitiateSignalBuilder*) clone;
|
||||
|
||||
- (InitiateSignal*) build;
|
||||
- (InitiateSignal*) buildPartial;
|
||||
|
||||
- (InitiateSignal_Builder*) mergeFrom:(InitiateSignal*) other;
|
||||
- (InitiateSignal_Builder*) mergeFromCodedInputStream:(PBCodedInputStream*) input;
|
||||
- (InitiateSignal_Builder*) mergeFromCodedInputStream:(PBCodedInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
|
||||
- (InitiateSignalBuilder*) mergeFrom:(InitiateSignal*) other;
|
||||
- (InitiateSignalBuilder*) mergeFromCodedInputStream:(PBCodedInputStream*) input;
|
||||
- (InitiateSignalBuilder*) mergeFromCodedInputStream:(PBCodedInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
|
||||
|
||||
- (BOOL) hasInitiator;
|
||||
- (NSString*) initiator;
|
||||
- (InitiateSignal_Builder*) setInitiator:(NSString*) value;
|
||||
- (InitiateSignal_Builder*) clearInitiator;
|
||||
- (InitiateSignalBuilder*) setInitiator:(NSString*) value;
|
||||
- (InitiateSignalBuilder*) clearInitiator;
|
||||
|
||||
- (BOOL) hasSessionId;
|
||||
- (int64_t) sessionId;
|
||||
- (InitiateSignal_Builder*) setSessionId:(int64_t) value;
|
||||
- (InitiateSignal_Builder*) clearSessionId;
|
||||
- (UInt64) sessionId;
|
||||
- (InitiateSignalBuilder*) setSessionId:(UInt64) value;
|
||||
- (InitiateSignalBuilder*) clearSessionId;
|
||||
|
||||
- (BOOL) hasPort;
|
||||
- (int32_t) port;
|
||||
- (InitiateSignal_Builder*) setPort:(int32_t) value;
|
||||
- (InitiateSignal_Builder*) clearPort;
|
||||
- (UInt32) port;
|
||||
- (InitiateSignalBuilder*) setPort:(UInt32) value;
|
||||
- (InitiateSignalBuilder*) clearPort;
|
||||
|
||||
- (BOOL) hasServerName;
|
||||
- (NSString*) serverName;
|
||||
- (InitiateSignal_Builder*) setServerName:(NSString*) value;
|
||||
- (InitiateSignal_Builder*) clearServerName;
|
||||
- (InitiateSignalBuilder*) setServerName:(NSString*) value;
|
||||
- (InitiateSignalBuilder*) clearServerName;
|
||||
|
||||
- (BOOL) hasVersion;
|
||||
- (int32_t) version;
|
||||
- (InitiateSignal_Builder*) setVersion:(int32_t) value;
|
||||
- (InitiateSignal_Builder*) clearVersion;
|
||||
- (UInt32) version;
|
||||
- (InitiateSignalBuilder*) setVersion:(UInt32) value;
|
||||
- (InitiateSignalBuilder*) clearVersion;
|
||||
@end
|
||||
|
||||
|
||||
// @@protoc_insertion_point(global_scope)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
|
||||
#import "InitiateSignal.pb.h"
|
||||
// @@protoc_insertion_point(imports)
|
||||
|
||||
@implementation InitiateSignalRoot
|
||||
static PBExtensionRegistry* extensionRegistry = nil;
|
||||
|
@ -20,11 +21,11 @@ static PBExtensionRegistry* extensionRegistry = nil;
|
|||
@end
|
||||
|
||||
@interface InitiateSignal ()
|
||||
@property (retain) NSString* initiator;
|
||||
@property int64_t sessionId;
|
||||
@property int32_t port;
|
||||
@property (retain) NSString* serverName;
|
||||
@property int32_t version;
|
||||
@property (strong) NSString* initiator;
|
||||
@property UInt64 sessionId;
|
||||
@property UInt32 port;
|
||||
@property (strong) NSString* serverName;
|
||||
@property UInt32 version;
|
||||
@end
|
||||
|
||||
@implementation InitiateSignal
|
||||
|
@ -32,42 +33,38 @@ static PBExtensionRegistry* extensionRegistry = nil;
|
|||
- (BOOL) hasInitiator {
|
||||
return !!hasInitiator_;
|
||||
}
|
||||
- (void) setHasInitiator:(BOOL) value {
|
||||
hasInitiator_ = !!value;
|
||||
- (void) setHasInitiator:(BOOL) value_ {
|
||||
hasInitiator_ = !!value_;
|
||||
}
|
||||
@synthesize initiator;
|
||||
- (BOOL) hasSessionId {
|
||||
return !!hasSessionId_;
|
||||
}
|
||||
- (void) setHasSessionId:(BOOL) value {
|
||||
hasSessionId_ = !!value;
|
||||
- (void) setHasSessionId:(BOOL) value_ {
|
||||
hasSessionId_ = !!value_;
|
||||
}
|
||||
@synthesize sessionId;
|
||||
- (BOOL) hasPort {
|
||||
return !!hasPort_;
|
||||
}
|
||||
- (void) setHasPort:(BOOL) value {
|
||||
hasPort_ = !!value;
|
||||
- (void) setHasPort:(BOOL) value_ {
|
||||
hasPort_ = !!value_;
|
||||
}
|
||||
@synthesize port;
|
||||
- (BOOL) hasServerName {
|
||||
return !!hasServerName_;
|
||||
}
|
||||
- (void) setHasServerName:(BOOL) value {
|
||||
hasServerName_ = !!value;
|
||||
- (void) setHasServerName:(BOOL) value_ {
|
||||
hasServerName_ = !!value_;
|
||||
}
|
||||
@synthesize serverName;
|
||||
- (BOOL) hasVersion {
|
||||
return !!hasVersion_;
|
||||
}
|
||||
- (void) setHasVersion:(BOOL) value {
|
||||
hasVersion_ = !!value;
|
||||
- (void) setHasVersion:(BOOL) value_ {
|
||||
hasVersion_ = !!value_;
|
||||
}
|
||||
@synthesize version;
|
||||
- (void) dealloc {
|
||||
self.initiator = nil;
|
||||
self.serverName = nil;
|
||||
}
|
||||
- (id) init {
|
||||
if ((self = [super init])) {
|
||||
self.initiator = @"";
|
||||
|
@ -111,31 +108,31 @@ static InitiateSignal* defaultInitiateSignalInstance = nil;
|
|||
}
|
||||
[self.unknownFields writeToCodedOutputStream:output];
|
||||
}
|
||||
- (int32_t) serializedSize {
|
||||
int32_t size = memoizedSerializedSize;
|
||||
if (size != -1) {
|
||||
return size;
|
||||
- (SInt32) serializedSize {
|
||||
__block SInt32 size_ = memoizedSerializedSize;
|
||||
if (size_ != -1) {
|
||||
return size_;
|
||||
}
|
||||
|
||||
size = 0;
|
||||
size_ = 0;
|
||||
if (self.hasInitiator) {
|
||||
size += computeStringSize(1, self.initiator);
|
||||
size_ += computeStringSize(1, self.initiator);
|
||||
}
|
||||
if (self.hasSessionId) {
|
||||
size += computeUInt64Size(2, self.sessionId);
|
||||
size_ += computeUInt64Size(2, self.sessionId);
|
||||
}
|
||||
if (self.hasPort) {
|
||||
size += computeUInt32Size(3, self.port);
|
||||
size_ += computeUInt32Size(3, self.port);
|
||||
}
|
||||
if (self.hasServerName) {
|
||||
size += computeStringSize(4, self.serverName);
|
||||
size_ += computeStringSize(4, self.serverName);
|
||||
}
|
||||
if (self.hasVersion) {
|
||||
size += computeUInt32Size(5, self.version);
|
||||
size_ += computeUInt32Size(5, self.version);
|
||||
}
|
||||
size += self.unknownFields.serializedSize;
|
||||
memoizedSerializedSize = size;
|
||||
return size;
|
||||
size_ += self.unknownFields.serializedSize;
|
||||
memoizedSerializedSize = size_;
|
||||
return size_;
|
||||
}
|
||||
+ (InitiateSignal*) parseFromData:(NSData*) data {
|
||||
return (InitiateSignal*)[[[InitiateSignal builder] mergeFromData:data] build];
|
||||
|
@ -155,26 +152,85 @@ static InitiateSignal* defaultInitiateSignalInstance = nil;
|
|||
+ (InitiateSignal*) parseFromCodedInputStream:(PBCodedInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry {
|
||||
return (InitiateSignal*)[[[InitiateSignal builder] mergeFromCodedInputStream:input extensionRegistry:extensionRegistry] build];
|
||||
}
|
||||
+ (InitiateSignal_Builder*) builder {
|
||||
return [[InitiateSignal_Builder alloc] init];
|
||||
+ (InitiateSignalBuilder*) builder {
|
||||
return [[InitiateSignalBuilder alloc] init];
|
||||
}
|
||||
+ (InitiateSignal_Builder*) builderWithPrototype:(InitiateSignal*) prototype {
|
||||
+ (InitiateSignalBuilder*) builderWithPrototype:(InitiateSignal*) prototype {
|
||||
return [[InitiateSignal builder] mergeFrom:prototype];
|
||||
}
|
||||
- (InitiateSignal_Builder*) builder {
|
||||
- (InitiateSignalBuilder*) builder {
|
||||
return [InitiateSignal builder];
|
||||
}
|
||||
@end
|
||||
|
||||
@interface InitiateSignal_Builder()
|
||||
@property (retain) InitiateSignal* result;
|
||||
@end
|
||||
|
||||
@implementation InitiateSignal_Builder
|
||||
@synthesize result;
|
||||
- (void) dealloc {
|
||||
self.result = nil;
|
||||
- (InitiateSignalBuilder*) toBuilder {
|
||||
return [InitiateSignal builderWithPrototype:self];
|
||||
}
|
||||
- (void) writeDescriptionTo:(NSMutableString*) output withIndent:(NSString*) indent {
|
||||
if (self.hasInitiator) {
|
||||
[output appendFormat:@"%@%@: %@\n", indent, @"initiator", self.initiator];
|
||||
}
|
||||
if (self.hasSessionId) {
|
||||
[output appendFormat:@"%@%@: %@\n", indent, @"sessionId", [NSNumber numberWithLongLong:self.sessionId]];
|
||||
}
|
||||
if (self.hasPort) {
|
||||
[output appendFormat:@"%@%@: %@\n", indent, @"port", [NSNumber numberWithInteger:self.port]];
|
||||
}
|
||||
if (self.hasServerName) {
|
||||
[output appendFormat:@"%@%@: %@\n", indent, @"serverName", self.serverName];
|
||||
}
|
||||
if (self.hasVersion) {
|
||||
[output appendFormat:@"%@%@: %@\n", indent, @"version", [NSNumber numberWithInteger:self.version]];
|
||||
}
|
||||
[self.unknownFields writeDescriptionTo:output withIndent:indent];
|
||||
}
|
||||
- (BOOL) isEqual:(id)other {
|
||||
if (other == self) {
|
||||
return YES;
|
||||
}
|
||||
if (![other isKindOfClass:[InitiateSignal class]]) {
|
||||
return NO;
|
||||
}
|
||||
InitiateSignal *otherMessage = other;
|
||||
return
|
||||
self.hasInitiator == otherMessage.hasInitiator &&
|
||||
(!self.hasInitiator || [self.initiator isEqual:otherMessage.initiator]) &&
|
||||
self.hasSessionId == otherMessage.hasSessionId &&
|
||||
(!self.hasSessionId || self.sessionId == otherMessage.sessionId) &&
|
||||
self.hasPort == otherMessage.hasPort &&
|
||||
(!self.hasPort || self.port == otherMessage.port) &&
|
||||
self.hasServerName == otherMessage.hasServerName &&
|
||||
(!self.hasServerName || [self.serverName isEqual:otherMessage.serverName]) &&
|
||||
self.hasVersion == otherMessage.hasVersion &&
|
||||
(!self.hasVersion || self.version == otherMessage.version) &&
|
||||
(self.unknownFields == otherMessage.unknownFields || (self.unknownFields != nil && [self.unknownFields isEqual:otherMessage.unknownFields]));
|
||||
}
|
||||
- (NSUInteger) hash {
|
||||
__block NSUInteger hashCode = 7;
|
||||
if (self.hasInitiator) {
|
||||
hashCode = hashCode * 31 + [self.initiator hash];
|
||||
}
|
||||
if (self.hasSessionId) {
|
||||
hashCode = hashCode * 31 + [[NSNumber numberWithLongLong:self.sessionId] hash];
|
||||
}
|
||||
if (self.hasPort) {
|
||||
hashCode = hashCode * 31 + [[NSNumber numberWithInteger:self.port] hash];
|
||||
}
|
||||
if (self.hasServerName) {
|
||||
hashCode = hashCode * 31 + [self.serverName hash];
|
||||
}
|
||||
if (self.hasVersion) {
|
||||
hashCode = hashCode * 31 + [[NSNumber numberWithInteger:self.version] hash];
|
||||
}
|
||||
hashCode = hashCode * 31 + [self.unknownFields hash];
|
||||
return hashCode;
|
||||
}
|
||||
@end
|
||||
|
||||
@interface InitiateSignalBuilder()
|
||||
@property (strong) InitiateSignal* result;
|
||||
@end
|
||||
|
||||
@implementation InitiateSignalBuilder
|
||||
@synthesize result;
|
||||
- (id) init {
|
||||
if ((self = [super init])) {
|
||||
self.result = [[InitiateSignal alloc] init];
|
||||
|
@ -184,11 +240,11 @@ static InitiateSignal* defaultInitiateSignalInstance = nil;
|
|||
- (PBGeneratedMessage*) internalGetResult {
|
||||
return result;
|
||||
}
|
||||
- (InitiateSignal_Builder*) clear {
|
||||
- (InitiateSignalBuilder*) clear {
|
||||
self.result = [[InitiateSignal alloc] init];
|
||||
return self;
|
||||
}
|
||||
- (InitiateSignal_Builder*) clone {
|
||||
- (InitiateSignalBuilder*) clone {
|
||||
return [InitiateSignal builderWithPrototype:result];
|
||||
}
|
||||
- (InitiateSignal*) defaultInstance {
|
||||
|
@ -203,7 +259,7 @@ static InitiateSignal* defaultInitiateSignalInstance = nil;
|
|||
self.result = nil;
|
||||
return returnMe;
|
||||
}
|
||||
- (InitiateSignal_Builder*) mergeFrom:(InitiateSignal*) other {
|
||||
- (InitiateSignalBuilder*) mergeFrom:(InitiateSignal*) other {
|
||||
if (other == [InitiateSignal defaultInstance]) {
|
||||
return self;
|
||||
}
|
||||
|
@ -225,13 +281,13 @@ static InitiateSignal* defaultInitiateSignalInstance = nil;
|
|||
[self mergeUnknownFields:other.unknownFields];
|
||||
return self;
|
||||
}
|
||||
- (InitiateSignal_Builder*) mergeFromCodedInputStream:(PBCodedInputStream*) input {
|
||||
- (InitiateSignalBuilder*) mergeFromCodedInputStream:(PBCodedInputStream*) input {
|
||||
return [self mergeFromCodedInputStream:input extensionRegistry:[PBExtensionRegistry emptyRegistry]];
|
||||
}
|
||||
- (InitiateSignal_Builder*) mergeFromCodedInputStream:(PBCodedInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry {
|
||||
PBUnknownFieldSet_Builder* unknownFields = [PBUnknownFieldSet builderWithUnknownFields:self.unknownFields];
|
||||
- (InitiateSignalBuilder*) mergeFromCodedInputStream:(PBCodedInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry {
|
||||
PBUnknownFieldSetBuilder* unknownFields = [PBUnknownFieldSet builderWithUnknownFields:self.unknownFields];
|
||||
while (YES) {
|
||||
int32_t tag = [input readTag];
|
||||
SInt32 tag = [input readTag];
|
||||
switch (tag) {
|
||||
case 0:
|
||||
[self setUnknownFields:[unknownFields build]];
|
||||
|
@ -272,12 +328,12 @@ static InitiateSignal* defaultInitiateSignalInstance = nil;
|
|||
- (NSString*) initiator {
|
||||
return result.initiator;
|
||||
}
|
||||
- (InitiateSignal_Builder*) setInitiator:(NSString*) value {
|
||||
- (InitiateSignalBuilder*) setInitiator:(NSString*) value {
|
||||
result.hasInitiator = YES;
|
||||
result.initiator = value;
|
||||
return self;
|
||||
}
|
||||
- (InitiateSignal_Builder*) clearInitiator {
|
||||
- (InitiateSignalBuilder*) clearInitiator {
|
||||
result.hasInitiator = NO;
|
||||
result.initiator = @"";
|
||||
return self;
|
||||
|
@ -285,15 +341,15 @@ static InitiateSignal* defaultInitiateSignalInstance = nil;
|
|||
- (BOOL) hasSessionId {
|
||||
return result.hasSessionId;
|
||||
}
|
||||
- (int64_t) sessionId {
|
||||
- (UInt64) sessionId {
|
||||
return result.sessionId;
|
||||
}
|
||||
- (InitiateSignal_Builder*) setSessionId:(int64_t) value {
|
||||
- (InitiateSignalBuilder*) setSessionId:(UInt64) value {
|
||||
result.hasSessionId = YES;
|
||||
result.sessionId = value;
|
||||
return self;
|
||||
}
|
||||
- (InitiateSignal_Builder*) clearSessionId {
|
||||
- (InitiateSignalBuilder*) clearSessionId {
|
||||
result.hasSessionId = NO;
|
||||
result.sessionId = 0L;
|
||||
return self;
|
||||
|
@ -301,15 +357,15 @@ static InitiateSignal* defaultInitiateSignalInstance = nil;
|
|||
- (BOOL) hasPort {
|
||||
return result.hasPort;
|
||||
}
|
||||
- (int32_t) port {
|
||||
- (UInt32) port {
|
||||
return result.port;
|
||||
}
|
||||
- (InitiateSignal_Builder*) setPort:(int32_t) value {
|
||||
- (InitiateSignalBuilder*) setPort:(UInt32) value {
|
||||
result.hasPort = YES;
|
||||
result.port = value;
|
||||
return self;
|
||||
}
|
||||
- (InitiateSignal_Builder*) clearPort {
|
||||
- (InitiateSignalBuilder*) clearPort {
|
||||
result.hasPort = NO;
|
||||
result.port = 0;
|
||||
return self;
|
||||
|
@ -320,12 +376,12 @@ static InitiateSignal* defaultInitiateSignalInstance = nil;
|
|||
- (NSString*) serverName {
|
||||
return result.serverName;
|
||||
}
|
||||
- (InitiateSignal_Builder*) setServerName:(NSString*) value {
|
||||
- (InitiateSignalBuilder*) setServerName:(NSString*) value {
|
||||
result.hasServerName = YES;
|
||||
result.serverName = value;
|
||||
return self;
|
||||
}
|
||||
- (InitiateSignal_Builder*) clearServerName {
|
||||
- (InitiateSignalBuilder*) clearServerName {
|
||||
result.hasServerName = NO;
|
||||
result.serverName = @"";
|
||||
return self;
|
||||
|
@ -333,18 +389,20 @@ static InitiateSignal* defaultInitiateSignalInstance = nil;
|
|||
- (BOOL) hasVersion {
|
||||
return result.hasVersion;
|
||||
}
|
||||
- (int32_t) version {
|
||||
- (UInt32) version {
|
||||
return result.version;
|
||||
}
|
||||
- (InitiateSignal_Builder*) setVersion:(int32_t) value {
|
||||
- (InitiateSignalBuilder*) setVersion:(UInt32) value {
|
||||
result.hasVersion = YES;
|
||||
result.version = value;
|
||||
return self;
|
||||
}
|
||||
- (InitiateSignal_Builder*) clearVersion {
|
||||
- (InitiateSignalBuilder*) clearVersion {
|
||||
result.hasVersion = NO;
|
||||
result.version = 0;
|
||||
return self;
|
||||
}
|
||||
@end
|
||||
|
||||
|
||||
// @@protoc_insertion_point(global_scope)
|
||||
|
|
|
@ -72,8 +72,8 @@
|
|||
checkOperation(parsedPayload.initiator != nil);
|
||||
checkOperation(parsedPayload.serverName != nil);
|
||||
|
||||
int32_t interopVersion = parsedPayload.version;
|
||||
int64_t sessionId = parsedPayload.sessionId;
|
||||
unsigned int interopVersion = parsedPayload.version;
|
||||
unsigned long long sessionId = parsedPayload.sessionId;
|
||||
in_port_t relayUdpPort = (in_port_t)parsedPayload.port;
|
||||
NSString* relayServerName = parsedPayload.serverName;
|
||||
PhoneNumber* phoneNumber = [PhoneNumber phoneNumberFromE164:parsedPayload.initiator];
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
//
|
||||
// TSAccountManagement.h
|
||||
// TextSecureKit
|
||||
//
|
||||
// Created by Frederic Jacobs on 27/10/14.
|
||||
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "TSConstants.h"
|
||||
#import "TSNumberVerifier.h"
|
||||
|
||||
typedef void(^codeVerifierBlock)(TSNumberVerifier *numberVerifier);
|
||||
|
||||
@interface TSAccountManager : NSObject
|
||||
|
||||
/**
|
||||
* Returns if a user is registered or not
|
||||
*
|
||||
* @return registered or not
|
||||
*/
|
||||
|
||||
+ (BOOL)isRegistered;
|
||||
|
||||
/**
|
||||
* Returns registered number
|
||||
*
|
||||
* @return E164 formatted phone number
|
||||
*/
|
||||
|
||||
+ (NSString*)registeredNumber;
|
||||
|
||||
/**
|
||||
* The registration ID is unique to an installation of TextSecure, it allows to know if the app was reinstalled
|
||||
*
|
||||
* @return registrationID;
|
||||
*/
|
||||
|
||||
+ (int)getOrGenerateRegistrationId;
|
||||
|
||||
/**
|
||||
* Sets the user as registered
|
||||
*
|
||||
*/
|
||||
|
||||
+ (void)setRegistered:(BOOL)registered;
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
|
||||
/**
|
||||
* Request a verification challenge
|
||||
*
|
||||
* @param phoneNumber phone number to send verification challenge to
|
||||
* @param transport sms or voice call
|
||||
* @param successBlock block to execute on success of request
|
||||
* @param failureBlock block to execute on failure of request
|
||||
*/
|
||||
|
||||
+ (void)registerWithPhoneNumber:(NSString*)phoneNumber overTransport:(VerificationTransportType)transport success:(codeVerifierBlock)success failure:(failedRegistrationRequestBlock)failureBlock;
|
||||
|
||||
/**
|
||||
* Register's the device's push notification token with the server
|
||||
*
|
||||
* @param pushToken Apple's Push Token
|
||||
*/
|
||||
|
||||
+ (void)registerForPushNotifications:(NSData*)pushToken success:(successCompletionBlock)success failure:(failedVerificationBlock)failureBlock;
|
||||
|
||||
#endif
|
||||
|
||||
@end
|
|
@ -0,0 +1,124 @@
|
|||
//
|
||||
// TSAccountManagement.m
|
||||
// TextSecureKit
|
||||
//
|
||||
// Created by Frederic Jacobs on 27/10/14.
|
||||
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "NSData+Base64.h"
|
||||
#import "NSData+hexString.h"
|
||||
#import "NSURLSessionDataTask+StatusCode.h"
|
||||
|
||||
#import "SecurityUtils.h"
|
||||
#import "TSNetworkManager.h"
|
||||
#import "TSAccountManager.h"
|
||||
#import "TSRequestVerificationCodeRequest.h"
|
||||
#import "TSStorageManager+keyingMaterial.h"
|
||||
#import "TSNumberVerifier.h"
|
||||
#import "TSRegisterForPushRequest.h"
|
||||
#import "TSRegisterWithTokenRequest.h"
|
||||
|
||||
typedef void(^succesfullPushRegistrationBlock)(NSData *pushToken);
|
||||
|
||||
|
||||
@interface TSAccountManager ()
|
||||
|
||||
@property (nonatomic, retain) NSString *phoneNumberAwaitingVerification;
|
||||
|
||||
@end
|
||||
|
||||
@interface TSNumberVerifier ()
|
||||
|
||||
+ (instancetype)verifierWithPhoneNumber:(NSString*)phoneNumber;
|
||||
|
||||
@end
|
||||
|
||||
@implementation TSAccountManager
|
||||
|
||||
+ (BOOL)isRegistered {
|
||||
return [[TSStorageManager sharedManager] boolForKey:TSStorageIsRegistered inCollection:TSStorageInternalSettingsCollection];
|
||||
}
|
||||
|
||||
+ (void)setRegistered:(BOOL)registered{
|
||||
[[TSStorageManager sharedManager] setObject:registered?@YES:@NO forKey:TSStorageIsRegistered inCollection:TSStorageInternalSettingsCollection];
|
||||
}
|
||||
|
||||
+ (NSString *)registeredNumber {
|
||||
YapDatabaseConnection *dbConn = [[TSStorageManager sharedManager] databaseConnection];
|
||||
__block NSString *phoneNumber;
|
||||
|
||||
[dbConn readWithBlock:^(YapDatabaseReadTransaction *transaction) {
|
||||
phoneNumber = [transaction objectForKey:TSStorageRegisteredNumberKey inCollection:TSStorageUserAccountCollection];
|
||||
}];
|
||||
|
||||
return phoneNumber;
|
||||
}
|
||||
|
||||
+ (int)getOrGenerateRegistrationId {
|
||||
YapDatabaseConnection *dbConn = [[TSStorageManager sharedManager] databaseConnection];
|
||||
__block int registrationID;
|
||||
|
||||
[dbConn readWithBlock:^(YapDatabaseReadTransaction *transaction) {
|
||||
registrationID = [[transaction objectForKey:TSStorageLocalRegistrationId inCollection:TSStorageUserAccountCollection] intValue];
|
||||
}];
|
||||
|
||||
if (!registrationID) {
|
||||
YapDatabaseConnection *dbConn = [[TSStorageManager sharedManager] databaseConnection];
|
||||
|
||||
int localIdentifier = random()%16380;
|
||||
|
||||
[dbConn readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
|
||||
[transaction setObject:[NSNumber numberWithInt:localIdentifier]
|
||||
forKey:TSStorageLocalRegistrationId
|
||||
inCollection:TSStorageUserAccountCollection];
|
||||
}];
|
||||
}
|
||||
|
||||
return registrationID;
|
||||
}
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
|
||||
+ (void)registerWithPhoneNumber:(NSString*)phoneNumber overTransport:(VerificationTransportType)transport success:(codeVerifierBlock)successBlock failure:(failedRegistrationRequestBlock)failureBlock{
|
||||
|
||||
[[TSNetworkManager sharedManager] queueAuthenticatedRequest:[[TSRequestVerificationCodeRequest alloc]
|
||||
initRequestForPhoneNumber:phoneNumber transport:transport]
|
||||
success:^(NSURLSessionDataTask *task, id responseObject) {
|
||||
long statuscode = task.statusCode;
|
||||
|
||||
if (statuscode == 200 || statuscode == 204) {
|
||||
successBlock([TSNumberVerifier verifierWithPhoneNumber:phoneNumber]);
|
||||
} else{
|
||||
failureBlock();
|
||||
}
|
||||
|
||||
} failure:^(NSURLSessionDataTask *task, NSError *error) {
|
||||
failureBlock();
|
||||
}];
|
||||
}
|
||||
|
||||
+ (void)registerForPushNotifications:(NSData *)pushToken success:(successCompletionBlock)success failure:(failedVerificationBlock)failureBlock{
|
||||
|
||||
NSString *stringToken = [[pushToken description] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<> "]];
|
||||
|
||||
[[TSNetworkManager sharedManager] queueAuthenticatedRequest:[[TSRegisterForPushRequest alloc] initWithPushIdentifier:stringToken] success:^(NSURLSessionDataTask *task, id responseObject) {
|
||||
success();
|
||||
} failure:^(NSURLSessionDataTask *task, NSError *error) {
|
||||
switch ([task statusCode]) {
|
||||
case 401:
|
||||
failureBlock(kTSRegistrationFailureAuthentication);
|
||||
break;
|
||||
case 415:
|
||||
failureBlock(kTSRegistrationFailureRequest);
|
||||
break;
|
||||
default:
|
||||
failureBlock(kTSRegistrationFailureNetwork);
|
||||
break;
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@end
|
|
@ -0,0 +1,39 @@
|
|||
//
|
||||
// TSNumberVerifier.h
|
||||
// TextSecureKit
|
||||
//
|
||||
// Created by Frederic Jacobs on 31/10/14.
|
||||
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "TSConstants.h"
|
||||
|
||||
typedef NS_ENUM(NSUInteger, TSRegistrationFailure) {
|
||||
kTSRegistrationFailureAuthentication,
|
||||
kTSRegistrationFailureNetwork,
|
||||
kTSRegistrationFailureRateLimit,
|
||||
kTSRegistrationFailureWrongCode,
|
||||
kTSRegistrationFailureAlreadyRegistered,
|
||||
kTSRegistrationFailurePrekeys,
|
||||
kTSRegistrationFailurePushID,
|
||||
kTSRegistrationFailureRequest
|
||||
};
|
||||
|
||||
typedef void(^failedVerificationBlock)(TSRegistrationFailure failureType);
|
||||
|
||||
@interface TSNumberVerifier : NSObject
|
||||
|
||||
/**
|
||||
* Verify verification challenge code. To be called only after registerWithPhoneNumber succeeded
|
||||
*
|
||||
* @param verificationCode the verification code received
|
||||
* @param successBlock block to execute on success of request
|
||||
* @param failureBlock block to execute on failure of request
|
||||
*/
|
||||
|
||||
- (void)verifyCode:(NSString*)verificationCode success:(successCompletionBlock)successBlock failure:(failedVerificationBlock)failureBlock;
|
||||
|
||||
+ (void)registerPhoneNumber:(NSString*)phoneNumber withRedPhoneToken:(NSString*)registrationToken success:(successCompletionBlock)successBlock failure:(failedVerificationBlock)failureBlock;
|
||||
|
||||
@end
|
|
@ -0,0 +1,149 @@
|
|||
//
|
||||
// TSNumberVerifier.m
|
||||
// TextSecureKit
|
||||
//
|
||||
// Created by Frederic Jacobs on 31/10/14.
|
||||
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "NSData+Base64.h"
|
||||
#import "NSData+hexString.h"
|
||||
|
||||
#import "SecurityUtils.h"
|
||||
#import "TSAccountManager.h"
|
||||
#import "TSRegisterWithTokenRequest.h"
|
||||
#import "TSServerCodeVerificationRequest.h"
|
||||
#import "TSStorageManager+keyingMaterial.h"
|
||||
#import "TSNetworkManager.h"
|
||||
#import "TSNumberVerifier.h"
|
||||
|
||||
#import "TSPrekeyManager.h"
|
||||
|
||||
@interface TSNumberVerifier ()
|
||||
|
||||
@property (nonatomic, readonly) NSString *phoneNumber;
|
||||
|
||||
@end
|
||||
|
||||
@implementation TSNumberVerifier
|
||||
|
||||
- (instancetype)initWithNumber:(NSString*)string {
|
||||
self = [super init];
|
||||
|
||||
if (self) {
|
||||
_phoneNumber = string;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
+ (instancetype)verifierWithPhoneNumber:(NSString*)phoneNumber {
|
||||
TSNumberVerifier *verifier = [[TSNumberVerifier alloc] initWithNumber:phoneNumber];
|
||||
return verifier;
|
||||
}
|
||||
|
||||
+ (void)registerPhoneNumber:(NSString*)phoneNumber withRedPhoneToken:(NSString*)registrationToken success:(successCompletionBlock)successBlock failure:(failedVerificationBlock)failureBlock{
|
||||
NSString *authToken = [self generateNewAccountAuthenticationToken];
|
||||
NSString *signalingKey = [self generateNewSignalingKeyToken];
|
||||
|
||||
TSRegisterWithTokenRequest *request = [[TSRegisterWithTokenRequest alloc] initWithVerificationToken:registrationToken signalingKey:signalingKey authKey:authToken];
|
||||
|
||||
[[TSNetworkManager sharedManager] queueAuthenticatedRequest:request success:^(NSURLSessionDataTask *task, id responseObject) {
|
||||
|
||||
NSHTTPURLResponse *response = (NSHTTPURLResponse *)task.response;
|
||||
long statuscode = response.statusCode;
|
||||
|
||||
if (statuscode == 200 || statuscode == 204) {
|
||||
|
||||
[TSStorageManager storeServerToken:authToken signalingKey:signalingKey phoneNumber:phoneNumber];
|
||||
|
||||
[[self class] registerPushIdWithSuccess:successBlock failure:failureBlock];
|
||||
|
||||
} else{
|
||||
failureBlock(kTSRegistrationFailureNetwork);
|
||||
}
|
||||
|
||||
} failure:^(NSURLSessionDataTask *task, NSError *error) {
|
||||
|
||||
}];
|
||||
|
||||
|
||||
}
|
||||
|
||||
- (void)verifyCode:(NSString*)verificationCode success:(successCompletionBlock)successBlock failure:(failedVerificationBlock)failureBlock {
|
||||
NSString *authToken = [[self class] generateNewAccountAuthenticationToken];
|
||||
NSString *signalingKey = [[self class] generateNewSignalingKeyToken];
|
||||
NSString *phoneNumber = self.phoneNumber;
|
||||
|
||||
TSServerCodeVerificationRequest *request = [[TSServerCodeVerificationRequest alloc] initWithVerificationCode:verificationCode signalingKey:signalingKey authKey:authToken];
|
||||
request.numberToValidate = phoneNumber;
|
||||
|
||||
[[TSNetworkManager sharedManager] queueAuthenticatedRequest:request success:^(NSURLSessionDataTask *task, id responseObject) {
|
||||
|
||||
NSHTTPURLResponse *response = (NSHTTPURLResponse *)task.response;
|
||||
long statuscode = response.statusCode;
|
||||
|
||||
if (statuscode == 200 || statuscode == 204) {
|
||||
|
||||
[TSStorageManager storeServerToken:authToken signalingKey:signalingKey phoneNumber:phoneNumber];
|
||||
|
||||
[[self class] registerPushIdWithSuccess:successBlock failure:failureBlock];
|
||||
|
||||
} else{
|
||||
failureBlock(kTSRegistrationFailureNetwork);
|
||||
}
|
||||
|
||||
} failure:^(NSURLSessionDataTask *task, NSError *error) {
|
||||
NSHTTPURLResponse *response = (NSHTTPURLResponse *)task.response;
|
||||
long statuscode = response.statusCode;
|
||||
|
||||
switch (statuscode) {
|
||||
case 403: // Wrong verification code
|
||||
failureBlock(kTSRegistrationFailureWrongCode);
|
||||
break;
|
||||
case 413: // Rate limit exceeded
|
||||
failureBlock(kTSRegistrationFailureRateLimit);
|
||||
break;
|
||||
case 417: // Number already registered
|
||||
[[self class] registerPushIdWithSuccess:successBlock failure:failureBlock];
|
||||
break;
|
||||
default:
|
||||
failureBlock(kTSRegistrationFailureNetwork);
|
||||
break;
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
|
||||
|
||||
+ (void)registerPushIdWithSuccess:(successCompletionBlock)successBlock failure:(failedVerificationBlock)failureBlock {
|
||||
[TSAccountManager registerForPushNotifications:[@"A FAKE TOKEN" dataUsingEncoding:NSUTF8StringEncoding] success:^{
|
||||
[self registerPreKeys:successBlock failure:failureBlock];
|
||||
} failure:failureBlock];;
|
||||
|
||||
}
|
||||
|
||||
+ (void)registerPreKeys:(successCompletionBlock)successBlock failure:(failedVerificationBlock)failureBlock {
|
||||
[TSPreKeyManager registerPreKeysWithSuccess:^{
|
||||
[TSAccountManager setRegistered:YES];
|
||||
successBlock();
|
||||
} failure:failureBlock];
|
||||
}
|
||||
|
||||
|
||||
#pragma mark Server keying material
|
||||
|
||||
+ (NSString*)generateNewAccountAuthenticationToken {
|
||||
NSData *authToken = [SecurityUtils generateRandomBytes:16];
|
||||
NSString *authTokenPrint = [[NSData dataWithData:authToken] hexadecimalString];
|
||||
return authTokenPrint;
|
||||
}
|
||||
|
||||
+ (NSString*)generateNewSignalingKeyToken {
|
||||
/*The signalingKey is 32 bytes of AES material (256bit AES) and 20 bytes of Hmac key material (HmacSHA1) concatenated into a 52 byte slug that is base64 encoded. */
|
||||
NSData *signalingKeyToken = [SecurityUtils generateRandomBytes:52];
|
||||
NSString *signalingKeyTokenPrint = [[NSData dataWithData:signalingKeyToken] base64EncodedString];
|
||||
return signalingKeyTokenPrint;
|
||||
}
|
||||
|
||||
@end
|
|
@ -0,0 +1,17 @@
|
|||
//
|
||||
// TSPrekeyManager.h
|
||||
// TextSecureKit
|
||||
//
|
||||
// Created by Frederic Jacobs on 07/11/14.
|
||||
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "TSConstants.h"
|
||||
#import "TSNumberVerifier.h"
|
||||
|
||||
@interface TSPreKeyManager : NSObject
|
||||
|
||||
+ (void)registerPreKeysWithSuccess:(successCompletionBlock)success failure:(failedVerificationBlock)failureBlock;
|
||||
|
||||
@end
|
|
@ -0,0 +1,50 @@
|
|||
//
|
||||
// TSPrekeyManager.m
|
||||
// TextSecureKit
|
||||
//
|
||||
// Created by Frederic Jacobs on 07/11/14.
|
||||
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "TSPreKeyManager.h"
|
||||
#import "TSStorageManager.h"
|
||||
#import "TSStorageManager+PreKeyStore.h"
|
||||
#import "TSStorageManager+SignedPreKeyStore.h"
|
||||
#import "TSStorageManager+IdentityKeyStore.h"
|
||||
#import "TSNetworkManager.h"
|
||||
#import "TSRegisterPrekeysRequest.h"
|
||||
|
||||
@implementation TSPreKeyManager
|
||||
|
||||
+ (void)registerPreKeysWithSuccess:(successCompletionBlock)success failure:(failedVerificationBlock)failureBlock{
|
||||
TSStorageManager *storageManager = [TSStorageManager sharedManager];
|
||||
ECKeyPair *identityKeyPair = [storageManager identityKeyPair];
|
||||
|
||||
if (!identityKeyPair) {
|
||||
[storageManager generateNewIdentityKey];
|
||||
identityKeyPair = [storageManager identityKeyPair];
|
||||
}
|
||||
|
||||
PreKeyRecord *lastResortPreKey = [storageManager getOrGenerateLastResortKey];
|
||||
SignedPreKeyRecord *signedPreKey = [storageManager generateRandomSignedRecord];
|
||||
|
||||
NSArray *preKeys = [storageManager generatePreKeyRecords];
|
||||
|
||||
TSRegisterPrekeysRequest *request = [[TSRegisterPrekeysRequest alloc] initWithPrekeyArray:preKeys
|
||||
identityKey:[storageManager identityKeyPair].publicKey
|
||||
signedPreKeyRecord:signedPreKey
|
||||
preKeyLastResort:lastResortPreKey];
|
||||
|
||||
[[TSNetworkManager sharedManager] queueAuthenticatedRequest:request success:^(NSURLSessionDataTask *task, id responseObject) {
|
||||
[storageManager storePreKeyRecords:preKeys];
|
||||
[storageManager storeSignedPreKey:signedPreKey.Id signedPreKeyRecord:signedPreKey];
|
||||
|
||||
success();
|
||||
|
||||
} failure:^(NSURLSessionDataTask *task, NSError *error) {
|
||||
failureBlock(kTSRegistrationFailureNetwork);
|
||||
}];
|
||||
|
||||
}
|
||||
|
||||
@end
|
|
@ -0,0 +1,42 @@
|
|||
//
|
||||
// TSContact.h
|
||||
// TextSecureKit
|
||||
//
|
||||
// Created by Frederic Jacobs on 12/11/14.
|
||||
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <YapDatabase/YapDatabaseTransaction.h>
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <AddressBook/AddressBook.h>
|
||||
#endif
|
||||
|
||||
#import "TSInteraction.h"
|
||||
#import "TSYapDatabaseObject.h"
|
||||
|
||||
typedef NS_OPTIONS(NSInteger, TSServicesAvailable){
|
||||
TSServiceRedPhone,
|
||||
TSServiceTextSecure
|
||||
};
|
||||
|
||||
/**
|
||||
* TSContacts always have one property, the identifier they are registered with on TextSecure. All the rest is optional.
|
||||
*/
|
||||
|
||||
@interface TSContact : TSYapDatabaseObject
|
||||
|
||||
- (instancetype)initWithRecipientId:(NSString*)recipientId;
|
||||
|
||||
- (TSServicesAvailable)availableServices;
|
||||
- (TSInteraction*)lastMessageWithTransaction:(YapDatabaseReadTransaction *)transaction;
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
- (ABRecordID*)addressBookID;
|
||||
- (NSString*)firstName;
|
||||
- (NSString*)lastName;
|
||||
#endif
|
||||
|
||||
@end
|
|
@ -0,0 +1,31 @@
|
|||
//
|
||||
// TSContact.m
|
||||
// TextSecureKit
|
||||
//
|
||||
// Created by Frederic Jacobs on 12/11/14.
|
||||
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "TSContact.h"
|
||||
|
||||
static NSString *recipientKey = @"TSIdentifierRecipientIdKey";
|
||||
|
||||
@implementation TSContact
|
||||
|
||||
+ (BOOL)supportsSecureCoding{
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (id)initWithCoder:(NSCoder *)aDecoder{
|
||||
NSString *recipientId = [aDecoder decodeObjectOfClass:[NSString class] forKey:recipientKey];
|
||||
return [self initWithRecipientId:recipientId];
|
||||
}
|
||||
|
||||
|
||||
+ (NSString*)collection{
|
||||
return @"TSContactCollection";
|
||||
}
|
||||
|
||||
# pragma mark AddressBook Lookups
|
||||
|
||||
@end
|
|
@ -0,0 +1,27 @@
|
|||
//
|
||||
// TSGroup.h
|
||||
// TextSecureKit
|
||||
//
|
||||
// Created by Frederic Jacobs on 12/11/14.
|
||||
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "TSAttachement.h"
|
||||
|
||||
#import "TSYapDatabaseObject.h"
|
||||
|
||||
@interface TSGroup : TSYapDatabaseObject
|
||||
|
||||
@property (nonatomic) NSString *name; // Name of the group
|
||||
@property (nonatomic) TSAttachement *avatar; // Link to the attachement object (group picture)
|
||||
@property (nonatomic) NSSet *members; // Each member of the discussion is a TSUser
|
||||
|
||||
- (NSData*)groupIdentifier;
|
||||
|
||||
+ (TSGroup*)groupWithId:(NSData*)id;
|
||||
|
||||
- (NSSet*)membersIdentifier;
|
||||
|
||||
|
||||
@end
|
|
@ -0,0 +1,17 @@
|
|||
//
|
||||
// TSGroup.m
|
||||
// TextSecureKit
|
||||
//
|
||||
// Created by Frederic Jacobs on 12/11/14.
|
||||
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "TSGroup.h"
|
||||
|
||||
@implementation TSGroup
|
||||
|
||||
+ (NSString*)collection{
|
||||
return @"TSGroup";
|
||||
}
|
||||
|
||||
@end
|
|
@ -0,0 +1,31 @@
|
|||
//
|
||||
// TSRecipient.h
|
||||
// TextSecureKit
|
||||
//
|
||||
// Created by Frederic Jacobs on 17/11/14.
|
||||
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "TSYapDatabaseObject.h"
|
||||
|
||||
@interface TSRecipient : TSYapDatabaseObject
|
||||
|
||||
- (instancetype)initWithTextSecureIdentifier:(NSString*)textSecureIdentifier relay:(NSString*)relay;
|
||||
|
||||
+ (instancetype)recipientWithTextSecureIdentifier:(NSString*)textSecureIdentifier withTransaction:(YapDatabaseReadTransaction*)transaction;
|
||||
|
||||
- (NSSet*)devices; //NSNumbers
|
||||
|
||||
- (void)addDevices:(NSSet *)set;
|
||||
|
||||
- (void)removeDevices:(NSSet *)set;
|
||||
|
||||
#pragma mark Fingerprint verification
|
||||
|
||||
- (BOOL)hasVerifiedFingerprint;
|
||||
|
||||
- (void)setFingerPrintVerified:(BOOL)verified transaction:(YapDatabaseReadTransaction*)transaction;
|
||||
|
||||
@property (nonatomic, readonly) NSString *relay;
|
||||
|
||||
@end
|
|
@ -0,0 +1,84 @@
|
|||
//
|
||||
// TSRecipient.m
|
||||
// TextSecureKit
|
||||
//
|
||||
// Created by Frederic Jacobs on 17/11/14.
|
||||
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "TSStorageManager+IdentityKeyStore.h"
|
||||
#import "TSRecipient.h"
|
||||
|
||||
@interface TSRecipient (){
|
||||
NSMutableSet *devices;
|
||||
NSData *verifiedKey;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation TSRecipient
|
||||
|
||||
+ (NSString*)collection{
|
||||
return @"TSRecipient";
|
||||
}
|
||||
|
||||
- (instancetype)initWithTextSecureIdentifier:(NSString*)textSecureIdentifier{
|
||||
self = [super initWithUniqueId:textSecureIdentifier];
|
||||
|
||||
if (self) {
|
||||
devices = [NSMutableSet setWithObject:[NSNumber numberWithInt:1]];
|
||||
verifiedKey = nil;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
+ (instancetype)recipientWithTextSecureIdentifier:(NSString*)textSecureIdentifier withTransaction:(YapDatabaseReadTransaction*)transaction{
|
||||
TSRecipient *recipient = [self fetchObjectWithUniqueID:textSecureIdentifier transaction:transaction];
|
||||
|
||||
if (!recipient) {
|
||||
recipient = [[self alloc] initWithTextSecureIdentifier:textSecureIdentifier];
|
||||
}
|
||||
return recipient;
|
||||
}
|
||||
|
||||
- (NSSet*)devices{
|
||||
return [devices copy];
|
||||
}
|
||||
|
||||
- (void)addDevices:(NSSet *)set{
|
||||
[devices unionSet:set];
|
||||
}
|
||||
|
||||
- (void)removeDevices:(NSSet *)set{
|
||||
[devices minusSet:set];
|
||||
}
|
||||
|
||||
#pragma mark Fingerprint verification
|
||||
|
||||
- (BOOL)hasVerifiedFingerprint{
|
||||
if (verifiedKey) {
|
||||
BOOL equalsStoredValue = [verifiedKey isEqualToData:[[TSStorageManager sharedManager] identityKeyForRecipientId:self.uniqueId]];
|
||||
|
||||
if (equalsStoredValue) {
|
||||
return YES;
|
||||
} else{
|
||||
verifiedKey = nil;
|
||||
return NO;
|
||||
}
|
||||
|
||||
} else{
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setFingerPrintVerified:(BOOL)verified transaction:(YapDatabaseReadTransaction*)transaction{
|
||||
if (verified) {
|
||||
verifiedKey = [[TSStorageManager sharedManager] identityKeyForRecipientId:self.uniqueId];
|
||||
} else{
|
||||
verifiedKey = nil;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@end
|