Merging UI code with some basic TextSecureKit code.

This commit is contained in:
Frederic Jacobs 2014-11-19 21:17:53 +01:00
parent a60bc8be92
commit 43af8c18e3
246 changed files with 8249 additions and 11045 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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));
}

View File

@ -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))

View File

@ -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);
}

View File

@ -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'

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

Before

Width:  |  Height:  |  Size: 7.7 KiB

After

Width:  |  Height:  |  Size: 7.7 KiB

View File

Before

Width:  |  Height:  |  Size: 8.1 KiB

After

Width:  |  Height:  |  Size: 8.1 KiB

View File

Before

Width:  |  Height:  |  Size: 8.5 KiB

After

Width:  |  Height:  |  Size: 8.5 KiB

View File

Before

Width:  |  Height:  |  Size: 6.3 KiB

After

Width:  |  Height:  |  Size: 6.3 KiB

View File

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

Before

Width:  |  Height:  |  Size: 888 B

After

Width:  |  Height:  |  Size: 888 B

View File

Before

Width:  |  Height:  |  Size: 5.0 KiB

After

Width:  |  Height:  |  Size: 5.0 KiB

View File

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

Before

Width:  |  Height:  |  Size: 8.0 KiB

After

Width:  |  Height:  |  Size: 8.0 KiB

View File

Before

Width:  |  Height:  |  Size: 6.4 KiB

After

Width:  |  Height:  |  Size: 6.4 KiB

View File

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View File

Before

Width:  |  Height:  |  Size: 674 B

After

Width:  |  Height:  |  Size: 674 B

View File

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 5.6 KiB

View File

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 52 KiB

View File

Before

Width:  |  Height:  |  Size: 6.2 KiB

After

Width:  |  Height:  |  Size: 6.2 KiB

View File

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

View File

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 34 KiB

View File

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 6.1 KiB

View File

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 9.7 KiB

After

Width:  |  Height:  |  Size: 9.7 KiB

View File

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

View File

Before

Width:  |  Height:  |  Size: 781 B

After

Width:  |  Height:  |  Size: 781 B

View File

Before

Width:  |  Height:  |  Size: 8.9 KiB

After

Width:  |  Height:  |  Size: 8.9 KiB

View File

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

View File

@ -50,8 +50,6 @@
</array>
<key>UILaunchStoryboardName</key>
<string>Storyboard</string>
<key>UIMainStoryboardFile</key>
<string>Storyboard</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>

View File

@ -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;
}

View File

@ -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>

View File

@ -1,7 +1,6 @@
#import <Foundation/Foundation.h>
#import "PhoneNumberDirectoryFilter.h"
#import "PropertyListPreferences.h"
#import "CallLogViewController.h"
#import "Zid.h"
@class PhoneNumber;

View File

@ -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

View File

@ -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;
}

View File

@ -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)

View File

@ -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)

View File

@ -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];

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

Some files were not shown because too many files have changed in this diff Show More