) builder extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
151 |
152 | /**
153 | * Reads a {@code group} field value from the stream and merges it into the
154 | * given {@link UnknownFieldSet}.
155 | */
156 | - (void) readUnknownGroup:(SInt32) fieldNumber builder:(PBUnknownFieldSetBuilder*) builder;
157 |
158 | /**
159 | * Verifies that the last call to readTag() returned the given tag value.
160 | * This is used to verify that a nested group ended with the correct
161 | * end tag.
162 | *
163 | * @throws InvalidProtocolBuffer {@code value} does not match the
164 | * last tag.
165 | */
166 | - (void) checkLastTagWas:(SInt32) value;
167 |
168 | @end
169 |
--------------------------------------------------------------------------------
/GCDAsyncSocket/ProtobufBuffer/CodedOutputStream.h:
--------------------------------------------------------------------------------
1 | // Protocol Buffers for Objective C
2 | //
3 | // Copyright 2010 Booyah Inc.
4 | // Copyright 2008 Cyrus Najmabadi
5 | //
6 | // Licensed under the Apache License, Version 2.0 (the "License");
7 | // you may not use this file except in compliance with the License.
8 | // You may obtain a copy of the License at
9 | //
10 | // http://www.apache.org/licenses/LICENSE-2.0
11 | //
12 | // Unless required by applicable law or agreed to in writing, software
13 | // distributed under the License is distributed on an "AS IS" BASIS,
14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | // See the License for the specific language governing permissions and
16 | // limitations under the License.
17 |
18 | /**
19 | * Encodes and writes protocol message fields.
20 | *
21 | * This class contains two kinds of methods: methods that write specific
22 | * protocol message constructs and field types (e.g. {@link #writeTag} and
23 | * {@link #writeInt32}) and methods that write low-level values (e.g.
24 | * {@link #writeRawVarint32} and {@link #writeRawBytes}). If you are
25 | * writing encoded protocol messages, you should use the former methods, but if
26 | * you are writing some other format of your own design, use the latter.
27 | *
28 | *
This class is totally unsynchronized.
29 | *
30 | * @author Cyrus Najmabadi
31 | */
32 | #import
33 |
34 | @class PBUnknownFieldSet;
35 | @class RingBuffer;
36 | @protocol PBMessage;
37 |
38 | @interface PBCodedOutputStream : NSObject {
39 | NSOutputStream *output;
40 | RingBuffer *buffer;
41 | }
42 |
43 | + (PBCodedOutputStream*) streamWithData:(NSMutableData*) data;
44 | + (PBCodedOutputStream*) streamWithOutputStream:(NSOutputStream*) output;
45 | + (PBCodedOutputStream*) streamWithOutputStream:(NSOutputStream*) output bufferSize:(SInt32) bufferSize;
46 |
47 | /**
48 | * Flushes the stream and forces any buffered bytes to be written. This
49 | * does not flush the underlying NSOutputStream. Returns free space in buffer.
50 | */
51 | - (void) flush;
52 |
53 | /** Write a single byte. */
54 | - (void) writeRawByte:(uint8_t) value;
55 |
56 | /** Encode and write a tag. */
57 | - (void) writeTag:(SInt32) fieldNumber format:(SInt32) format;
58 |
59 | /** Write a little-endian 32-bit integer. */
60 | - (void) writeRawLittleEndian32:(SInt32) value;
61 | /** Write a little-endian 64-bit integer. */
62 | - (void) writeRawLittleEndian64:(SInt64) value;
63 |
64 | /**
65 | * Encode and write a varint. {@code value} is treated as
66 | * unsigned, so it won't be sign-extended if negative.
67 | */
68 | - (void) writeRawVarint32:(SInt32) value;
69 | /** Encode and write a varint. */
70 | - (void) writeRawVarint64:(SInt64) value;
71 |
72 | //- (void) writeRawLittleEndian32:(SInt32) value;
73 | //- (void) writeRawLittleEndian64:(SInt64) value;
74 |
75 | /** Write an array of bytes. */
76 | - (void) writeRawData:(const NSData*) data;
77 | - (void) writeRawData:(const NSData*) data offset:(SInt32) offset length:(SInt32) length;
78 |
79 | - (void) writeData:(SInt32) fieldNumber value:(const NSData*) value;
80 |
81 | - (void) writeDouble:(SInt32) fieldNumber value:(Float64) value;
82 | - (void) writeFloat:(SInt32) fieldNumber value:(Float32) value;
83 | - (void) writeUInt64:(SInt32) fieldNumber value:(SInt64) value;
84 | - (void) writeInt64:(SInt32) fieldNumber value:(SInt64) value;
85 | - (void) writeInt32:(SInt32) fieldNumber value:(SInt32) value;
86 | - (void) writeFixed64:(SInt32) fieldNumber value:(SInt64) value;
87 | - (void) writeFixed32:(SInt32) fieldNumber value:(SInt32) value;
88 | - (void) writeBool:(SInt32) fieldNumber value:(BOOL) value;
89 | - (void) writeString:(SInt32) fieldNumber value:(const NSString*) value;
90 | - (void) writeGroup:(SInt32) fieldNumber value:(const id) value;
91 | - (void) writeUnknownGroup:(SInt32) fieldNumber value:(const PBUnknownFieldSet*) value;
92 | - (void) writeMessage:(SInt32) fieldNumber value:(const id) value;
93 | - (void) writeUInt32:(SInt32) fieldNumber value:(SInt32) value;
94 | - (void) writeSFixed32:(SInt32) fieldNumber value:(SInt32) value;
95 | - (void) writeSFixed64:(SInt32) fieldNumber value:(SInt64) value;
96 | - (void) writeSInt32:(SInt32) fieldNumber value:(SInt32) value;
97 | - (void) writeSInt64:(SInt32) fieldNumber value:(SInt64) value;
98 |
99 | - (void) writeDoubleNoTag:(Float64) value;
100 | - (void) writeFloatNoTag:(Float32) value;
101 | - (void) writeUInt64NoTag:(SInt64) value;
102 | - (void) writeInt64NoTag:(SInt64) value;
103 | - (void) writeInt32NoTag:(SInt32) value;
104 | - (void) writeFixed64NoTag:(SInt64) value;
105 | - (void) writeFixed32NoTag:(SInt32) value;
106 | - (void) writeBoolNoTag:(BOOL) value;
107 | - (void) writeStringNoTag:(const NSString*) value;
108 | - (void) writeGroupNoTag:(SInt32) fieldNumber value:(const id) value;
109 | - (void) writeUnknownGroupNoTag:(SInt32) fieldNumber value:(const PBUnknownFieldSet*) value;
110 | - (void) writeMessageNoTag:(const id) value;
111 | - (void) writeDataNoTag:(const NSData*) value;
112 | - (void) writeUInt32NoTag:(SInt32) value;
113 | - (void) writeEnumNoTag:(SInt32) value;
114 | - (void) writeSFixed32NoTag:(SInt32) value;
115 | - (void) writeSFixed64NoTag:(SInt64) value;
116 | - (void) writeSInt32NoTag:(SInt32) value;
117 | - (void) writeSInt64NoTag:(SInt64) value;
118 |
119 |
120 | /**
121 | * Write a MessageSet extension field to the stream. For historical reasons,
122 | * the wire format differs from normal fields.
123 | */
124 | - (void) writeMessageSetExtension:(SInt32) fieldNumber value:(const id) value;
125 |
126 | /**
127 | * Write an unparsed MessageSet extension field to the stream. For
128 | * historical reasons, the wire format differs from normal fields.
129 | */
130 | - (void) writeRawMessageSetExtension:(SInt32) fieldNumber value:(const NSData*) value;
131 |
132 | /**
133 | * Write an enum field, including tag, to the stream. Caller is responsible
134 | * for converting the enum value to its numeric value.
135 | */
136 | - (void) writeEnum:(SInt32) fieldNumber value:(SInt32) value;
137 |
138 | @end
139 |
--------------------------------------------------------------------------------
/GCDAsyncSocket/ProtobufBuffer/ConcreteExtensionField.h:
--------------------------------------------------------------------------------
1 | // Protocol Buffers for Objective C
2 | //
3 | // Copyright 2010 Booyah Inc.
4 | // Copyright 2008 Cyrus Najmabadi
5 | //
6 | // Licensed under the Apache License, Version 2.0 (the "License");
7 | // you may not use this file except in compliance with the License.
8 | // You may obtain a copy of the License at
9 | //
10 | // http://www.apache.org/licenses/LICENSE-2.0
11 | //
12 | // Unless required by applicable law or agreed to in writing, software
13 | // distributed under the License is distributed on an "AS IS" BASIS,
14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | // See the License for the specific language governing permissions and
16 | // limitations under the License.
17 |
18 | #import "ExtensionField.h"
19 |
20 | typedef enum {
21 | PBExtensionTypeBool,
22 | PBExtensionTypeFixed32,
23 | PBExtensionTypeSFixed32,
24 | PBExtensionTypeFloat,
25 | PBExtensionTypeFixed64,
26 | PBExtensionTypeSFixed64,
27 | PBExtensionTypeDouble,
28 | PBExtensionTypeInt32,
29 | PBExtensionTypeInt64,
30 | PBExtensionTypeSInt32,
31 | PBExtensionTypeSInt64,
32 | PBExtensionTypeUInt32,
33 | PBExtensionTypeUInt64,
34 | PBExtensionTypeBytes,
35 | PBExtensionTypeString,
36 | PBExtensionTypeMessage,
37 | PBExtensionTypeGroup,
38 | PBExtensionTypeEnum
39 | } PBExtensionType;
40 |
41 | @interface PBConcreteExtensionField : NSObject {
42 | @private
43 | PBExtensionType type;
44 |
45 | Class extendedClass;
46 | SInt32 fieldNumber;
47 | id defaultValue;
48 |
49 | Class messageOrGroupClass;
50 |
51 | BOOL isRepeated;
52 | BOOL isPacked;
53 | BOOL isMessageSetWireFormat;
54 | }
55 |
56 | + (PBConcreteExtensionField*) extensionWithType:(PBExtensionType) type
57 | extendedClass:(Class) extendedClass
58 | fieldNumber:(SInt32) fieldNumber
59 | defaultValue:(id) defaultValue
60 | messageOrGroupClass:(Class) messageOrGroupClass
61 | isRepeated:(BOOL) isRepeated
62 | isPacked:(BOOL) isPacked
63 | isMessageSetWireFormat:(BOOL) isMessageSetWireFormat;
64 |
65 | @end
66 |
--------------------------------------------------------------------------------
/GCDAsyncSocket/ProtobufBuffer/ExtendableMessage.h:
--------------------------------------------------------------------------------
1 | // Protocol Buffers for Objective C
2 | //
3 | // Copyright 2010 Booyah Inc.
4 | // Copyright 2008 Cyrus Najmabadi
5 | //
6 | // Licensed under the Apache License, Version 2.0 (the "License");
7 | // you may not use this file except in compliance with the License.
8 | // You may obtain a copy of the License at
9 | //
10 | // http://www.apache.org/licenses/LICENSE-2.0
11 | //
12 | // Unless required by applicable law or agreed to in writing, software
13 | // distributed under the License is distributed on an "AS IS" BASIS,
14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | // See the License for the specific language governing permissions and
16 | // limitations under the License.
17 |
18 | #import "GeneratedMessage.h"
19 |
20 | #import "ExtensionField.h"
21 |
22 | /**
23 | * Generated message classes for message types that contain extension ranges
24 | * subclass this.
25 | *
26 | * This class implements type-safe accessors for extensions. They
27 | * implement all the same operations that you can do with normal fields --
28 | * e.g. "has", "get", and "getCount" -- but for extensions. The extensions
29 | * are identified using instances of the class {@link GeneratedExtension};
30 | * the protocol compiler generates a static instance of this class for every
31 | * extension in its input. Through the magic of generics, all is made
32 | * type-safe.
33 | *
34 | *
For example, imagine you have the {@code .proto} file:
35 | *
36 | *
37 | * option java_class = "MyProto";
38 | *
39 | * message Foo {
40 | * extensions 1000 to max;
41 | * }
42 | *
43 | * extend Foo {
44 | * optional int32 bar;
45 | * }
46 | *
47 | *
48 | * Then you might write code like:
49 | *
50 | *
51 | * MyProto.Foo foo = getFoo();
52 | * int i = foo.getExtension(MyProto.bar);
53 | *
54 | *
55 | * See also {@link ExtendableBuilder}.
56 | */
57 | @interface PBExtendableMessage : PBGeneratedMessage {
58 | @private
59 | NSMutableDictionary* extensionMap;
60 | NSMutableDictionary* extensionRegistry;
61 | }
62 |
63 | @property (strong) NSMutableDictionary* extensionMap;
64 | @property (strong) NSMutableDictionary* extensionRegistry;
65 |
66 | - (BOOL) hasExtension:(id) extension;
67 | - (id) getExtension:(id) extension;
68 |
69 | //@protected
70 | - (BOOL) extensionsAreInitialized;
71 | - (SInt32) extensionsSerializedSize;
72 | - (void) writeExtensionsToCodedOutputStream:(PBCodedOutputStream*) output
73 | from:(SInt32) startInclusive
74 | to:(SInt32) endExclusive;
75 | - (void) writeExtensionDescriptionToMutableString:(NSMutableString*) output
76 | from:(SInt32) startInclusive
77 | to:(SInt32) endExclusive
78 | withIndent:(NSString*) indent;
79 | - (void) addExtensionDictionaryEntriesToMutableDictionary:(NSMutableDictionary*) output
80 | from:(int32_t) startInclusive
81 | to:(int32_t) endExclusive;
82 | - (BOOL) isEqualExtensionsInOther:(PBExtendableMessage*)otherMessage
83 | from:(SInt32) startInclusive
84 | to:(SInt32) endExclusive;
85 | - (NSUInteger) hashExtensionsFrom:(SInt32) startInclusive
86 | to:(SInt32) endExclusive;
87 |
88 |
89 |
90 | /* @internal */
91 | - (void) ensureExtensionIsRegistered:(id) extension;
92 |
93 | @end
94 |
--------------------------------------------------------------------------------
/GCDAsyncSocket/ProtobufBuffer/ExtendableMessage.m:
--------------------------------------------------------------------------------
1 | // Protocol Buffers for Objective C
2 | //
3 | // Copyright 2010 Booyah Inc.
4 | // Copyright 2008 Cyrus Najmabadi
5 | //
6 | // Licensed under the Apache License, Version 2.0 (the "License");
7 | // you may not use this file except in compliance with the License.
8 | // You may obtain a copy of the License at
9 | //
10 | // http://www.apache.org/licenses/LICENSE-2.0
11 | //
12 | // Unless required by applicable law or agreed to in writing, software
13 | // distributed under the License is distributed on an "AS IS" BASIS,
14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | // See the License for the specific language governing permissions and
16 | // limitations under the License.
17 |
18 | #import "ExtendableMessage.h"
19 |
20 | #import "ExtensionField.h"
21 |
22 | @implementation PBExtendableMessage
23 |
24 | @synthesize extensionMap;
25 | @synthesize extensionRegistry;
26 |
27 |
28 |
29 |
30 | - (BOOL) isInitialized:(id) object {
31 | if ([object isKindOfClass:[NSArray class]]) {
32 | for (id child in object) {
33 | if (![self isInitialized:child]) {
34 | return NO;
35 | }
36 | }
37 | } else if ([object conformsToProtocol:@protocol(PBMessage)]) {
38 | return [object isInitialized];
39 | }
40 |
41 | return YES;
42 | }
43 |
44 |
45 | - (BOOL) extensionsAreInitialized {
46 | return [self isInitialized:extensionMap.allValues];
47 | }
48 |
49 |
50 | - (id) getExtension:(id) extension {
51 | [self ensureExtensionIsRegistered:extension];
52 | id value = [extensionMap objectForKey:@([extension fieldNumber])];
53 | if (value != nil) {
54 | return value;
55 | }
56 |
57 | return [extension defaultValue];
58 | }
59 |
60 |
61 | - (void) ensureExtensionIsRegistered:(id) extension {
62 | if ([extension extendedClass] != [self class]) {
63 | @throw [NSException exceptionWithName:@"IllegalArgument" reason:@"Trying to use an extension for another type" userInfo:nil];
64 | }
65 |
66 | if (extensionRegistry == nil) {
67 | self.extensionRegistry = [NSMutableDictionary dictionary];
68 | }
69 | [extensionRegistry setObject:extension
70 | forKey:@([extension fieldNumber])];
71 | }
72 |
73 |
74 | - (BOOL) hasExtension:(id) extension {
75 | return nil != [extensionMap objectForKey:@([extension fieldNumber])];
76 | }
77 |
78 |
79 | - (void) writeExtensionsToCodedOutputStream:(PBCodedOutputStream*) output
80 | from:(SInt32) startInclusive
81 | to:(SInt32) endExclusive {
82 | // man, i really wish Cocoa had a Sorted/TreeMap
83 | NSArray* sortedKeys = [extensionMap.allKeys sortedArrayUsingSelector:@selector(compare:)];
84 | for (NSNumber* number in sortedKeys) {
85 | SInt32 fieldNumber = (SInt32)[number integerValue];
86 | if (fieldNumber >= startInclusive && fieldNumber < endExclusive) {
87 | id extension = [extensionRegistry objectForKey:number];
88 | id value = [extensionMap objectForKey:number];
89 | [extension writeValue:value includingTagToCodedOutputStream:output];
90 | }
91 | }
92 | }
93 |
94 |
95 | - (void) writeExtensionDescriptionToMutableString:(NSMutableString*) output
96 | from:(SInt32) startInclusive
97 | to:(SInt32) endExclusive
98 | withIndent:(NSString*) indent {
99 | NSArray* sortedKeys = [extensionMap.allKeys sortedArrayUsingSelector:@selector(compare:)];
100 | for (NSNumber* number in sortedKeys) {
101 | SInt32 fieldNumber = (SInt32)[number integerValue];
102 | if (fieldNumber >= startInclusive && fieldNumber < endExclusive) {
103 | id extension = [extensionRegistry objectForKey:number];
104 | id value = [extensionMap objectForKey:number];
105 | [extension writeDescriptionOf:value to:output withIndent:indent];
106 | }
107 | }
108 | }
109 |
110 | - (void) addExtensionDictionaryEntriesToMutableDictionary:(NSMutableDictionary*) output
111 | from:(int32_t) startInclusive
112 | to:(int32_t) endExclusive {
113 | NSArray* sortedKeys = [extensionMap.allKeys sortedArrayUsingSelector:@selector(compare:)];
114 | for (NSNumber* number in sortedKeys) {
115 | int32_t fieldNumber = [number intValue];
116 | if (fieldNumber >= startInclusive && fieldNumber < endExclusive) {
117 | id extension = [extensionRegistry objectForKey:number];
118 | id value = [extensionMap objectForKey:number];
119 | [extension addDictionaryEntriesOf:value to:output];
120 | }
121 | }
122 | }
123 |
124 | - (BOOL) isEqualExtensionsInOther:(PBExtendableMessage*)otherMessage
125 | from:(SInt32) startInclusive
126 | to:(SInt32) endExclusive {
127 | NSArray* sortedKeys = [extensionMap.allKeys sortedArrayUsingSelector:@selector(compare:)];
128 | for (NSNumber* number in sortedKeys) {
129 | SInt32 fieldNumber = (SInt32)[number integerValue];
130 | if (fieldNumber >= startInclusive && fieldNumber < endExclusive) {
131 | id value = [extensionMap objectForKey:number];
132 | id otherValue = [otherMessage.extensionMap objectForKey:number];
133 | if (![value isEqual:otherValue]) {
134 | return NO;
135 | }
136 | }
137 | }
138 | return YES;
139 | }
140 |
141 |
142 | - (NSUInteger) hashExtensionsFrom:(SInt32) startInclusive
143 | to:(SInt32) endExclusive {
144 | NSUInteger hashCode = 0;
145 | NSArray* sortedKeys = [extensionMap.allKeys sortedArrayUsingSelector:@selector(compare:)];
146 | for (NSNumber* number in sortedKeys) {
147 | SInt32 fieldNumber = (SInt32)[number integerValue];
148 | if (fieldNumber >= startInclusive && fieldNumber < endExclusive) {
149 | id value = [extensionMap objectForKey:number];
150 | hashCode = hashCode * 31 + (NSUInteger)[value hash];
151 | }
152 | }
153 | return hashCode;
154 | }
155 |
156 |
157 | - (SInt32) extensionsSerializedSize {
158 | SInt32 size = 0;
159 | for (NSNumber* number in extensionMap) {
160 | id extension = [extensionRegistry objectForKey:number];
161 | id value = [extensionMap objectForKey:number];
162 | size += [extension computeSerializedSizeIncludingTag:value];
163 | }
164 |
165 | return size;
166 | }
167 |
168 | @end
169 |
--------------------------------------------------------------------------------
/GCDAsyncSocket/ProtobufBuffer/ExtendableMessageBuilder.h:
--------------------------------------------------------------------------------
1 | // Protocol Buffers for Objective C
2 | //
3 | // Copyright 2010 Booyah Inc.
4 | // Copyright 2008 Cyrus Najmabadi
5 | //
6 | // Licensed under the Apache License, Version 2.0 (the "License");
7 | // you may not use this file except in compliance with the License.
8 | // You may obtain a copy of the License at
9 | //
10 | // http://www.apache.org/licenses/LICENSE-2.0
11 | //
12 | // Unless required by applicable law or agreed to in writing, software
13 | // distributed under the License is distributed on an "AS IS" BASIS,
14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | // See the License for the specific language governing permissions and
16 | // limitations under the License.
17 |
18 | #import "GeneratedMessageBuilder.h"
19 |
20 | #import "ExtensionField.h"
21 |
22 | @class PBExtendableMessage;
23 |
24 | /**
25 | * Generated message builders for message types that contain extension ranges
26 | * subclass this.
27 | *
28 | * This class implements type-safe accessors for extensions. They
29 | * implement all the same operations that you can do with normal fields --
30 | * e.g. "get", "set", and "add" -- but for extensions. The extensions are
31 | * identified using instances of the class {@link GeneratedExtension}; the
32 | * protocol compiler generates a static instance of this class for every
33 | * extension in its input. Through the magic of generics, all is made
34 | * type-safe.
35 | *
36 | *
For example, imagine you have the {@code .proto} file:
37 | *
38 | *
39 | * option java_class = "MyProto";
40 | *
41 | * message Foo {
42 | * extensions 1000 to max;
43 | * }
44 | *
45 | * extend Foo {
46 | * optional int32 bar;
47 | * }
48 | *
49 | *
50 | * Then you might write code like:
51 | *
52 | *
53 | * MyProto.Foo foo =
54 | * MyProto.Foo.newBuilder()
55 | * .setExtension(MyProto.bar, 123)
56 | * .build();
57 | *
58 | *
59 | * See also {@link ExtendableMessage}.
60 | */
61 | @interface PBExtendableMessageBuilder : PBGeneratedMessageBuilder {
62 | }
63 |
64 | - (id) getExtension:(id) extension;
65 | - (BOOL) hasExtension:(id) extension;
66 | - (PBExtendableMessageBuilder*) setExtension:(id) extension
67 | value:(id) value;
68 | - (PBExtendableMessageBuilder*) addExtension:(id) extension
69 | value:(id) value;
70 | - (PBExtendableMessageBuilder*) setExtension:(id) extension
71 | index:(SInt32) index
72 | value:(id) value;
73 | - (PBExtendableMessageBuilder*) clearExtension:(id) extension;
74 |
75 | /* @protected */
76 | - (void) mergeExtensionFields:(PBExtendableMessage*) other;
77 |
78 | @end
79 |
--------------------------------------------------------------------------------
/GCDAsyncSocket/ProtobufBuffer/ExtendableMessageBuilder.m:
--------------------------------------------------------------------------------
1 | // Protocol Buffers for Objective C
2 | //
3 | // Copyright 2010 Booyah Inc.
4 | // Copyright 2008 Cyrus Najmabadi
5 | //
6 | // Licensed under the Apache License, Version 2.0 (the "License");
7 | // you may not use this file except in compliance with the License.
8 | // You may obtain a copy of the License at
9 | //
10 | // http://www.apache.org/licenses/LICENSE-2.0
11 | //
12 | // Unless required by applicable law or agreed to in writing, software
13 | // distributed under the License is distributed on an "AS IS" BASIS,
14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | // See the License for the specific language governing permissions and
16 | // limitations under the License.
17 |
18 | #import "ExtendableMessageBuilder.h"
19 |
20 | #import "ExtendableMessage.h"
21 | #import "ExtensionRegistry.h"
22 | #import "WireFormat.h"
23 |
24 | @implementation PBExtendableMessageBuilder
25 |
26 | - (PBExtendableMessage*) internalGetResult {
27 | @throw [NSException exceptionWithName:@"ImproperSubclassing" reason:@"" userInfo:nil];
28 | }
29 |
30 |
31 | /**
32 | * Called by subclasses to parse an unknown field or an extension.
33 | * @return {@code YES} unless the tag is an end-group tag.
34 | */
35 | - (BOOL) parseUnknownField:(PBCodedInputStream*) input
36 | unknownFields:(PBUnknownFieldSetBuilder*) unknownFields
37 | extensionRegistry:(PBExtensionRegistry*) extensionRegistry
38 | tag:(SInt32) tag {
39 | PBExtendableMessage* message = [self internalGetResult];
40 | SInt32 wireType = PBWireFormatGetTagWireType(tag);
41 | SInt32 fieldNumber = PBWireFormatGetTagFieldNumber(tag);
42 |
43 | id extension = [extensionRegistry getExtension:[message class]
44 | fieldNumber:fieldNumber];
45 |
46 | if (extension != nil) {
47 | if ([extension wireType] == wireType) {
48 | [extension mergeFromCodedInputStream:input
49 | unknownFields:unknownFields
50 | extensionRegistry:extensionRegistry
51 | builder:self
52 | tag:tag];
53 | return YES;
54 | }
55 | }
56 |
57 | return [super parseUnknownField:input unknownFields:unknownFields extensionRegistry:extensionRegistry tag:tag];
58 | }
59 |
60 |
61 | - (id) getExtension:(id) extension {
62 | return [[self internalGetResult] getExtension:extension];
63 | }
64 |
65 |
66 | - (BOOL) hasExtension:(id) extension {
67 | return [[self internalGetResult] hasExtension:extension];
68 | }
69 |
70 |
71 | - (PBExtendableMessageBuilder*) setExtension:(id) extension
72 | value:(id) value {
73 | PBExtendableMessage* message = [self internalGetResult];
74 | [message ensureExtensionIsRegistered:extension];
75 |
76 | if ([extension isRepeated]) {
77 | @throw [NSException exceptionWithName:@"IllegalArgument" reason:@"Must call addExtension() for repeated types." userInfo:nil];
78 | }
79 |
80 | if (message.extensionMap == nil) {
81 | message.extensionMap = [NSMutableDictionary dictionary];
82 | }
83 | [message.extensionMap setObject:value forKey:@([extension fieldNumber])];
84 | return self;
85 | }
86 |
87 |
88 | - (PBExtendableMessageBuilder*) addExtension:(id) extension
89 | value:(id) value {
90 | PBExtendableMessage* message = [self internalGetResult];
91 | [message ensureExtensionIsRegistered:extension];
92 |
93 | if (![extension isRepeated]) {
94 | @throw [NSException exceptionWithName:@"IllegalArgument" reason:@"Must call setExtension() for singular types." userInfo:nil];
95 | }
96 |
97 | if (message.extensionMap == nil) {
98 | message.extensionMap = [NSMutableDictionary dictionary];
99 | }
100 | NSNumber* fieldNumber = @([extension fieldNumber]);
101 | NSMutableArray* list = [message.extensionMap objectForKey:fieldNumber];
102 | if (list == nil) {
103 | list = [NSMutableArray array];
104 | [message.extensionMap setObject:list forKey:fieldNumber];
105 | }
106 |
107 | [list addObject:value];
108 | return self;
109 | }
110 |
111 |
112 | - (PBExtendableMessageBuilder*) setExtension:(id) extension
113 | index:(SInt32) index
114 | value:(id) value {
115 | PBExtendableMessage* message = [self internalGetResult];
116 | [message ensureExtensionIsRegistered:extension];
117 |
118 | if (![extension isRepeated]) {
119 | @throw [NSException exceptionWithName:@"IllegalArgument" reason:@"Must call setExtension() for singular types." userInfo:nil];
120 | }
121 |
122 | if (message.extensionMap == nil) {
123 | message.extensionMap = [NSMutableDictionary dictionary];
124 | }
125 |
126 | NSNumber* fieldNumber = @([extension fieldNumber]);
127 | NSMutableArray* list = [message.extensionMap objectForKey:fieldNumber];
128 |
129 | [list replaceObjectAtIndex:index withObject:value];
130 |
131 | return self;
132 | }
133 |
134 |
135 | - (PBExtendableMessageBuilder*) clearExtension:(id) extension {
136 | PBExtendableMessage* message = [self internalGetResult];
137 | [message ensureExtensionIsRegistered:extension];
138 | [message.extensionMap removeObjectForKey:@([extension fieldNumber])];
139 |
140 | return self;
141 | }
142 |
143 |
144 | - (void) mergeExtensionFields:(PBExtendableMessage*) other {
145 | PBExtendableMessage* thisMessage = [self internalGetResult];
146 | if ([thisMessage class] != [other class]) {
147 | @throw [NSException exceptionWithName:@"IllegalArgument" reason:@"Cannot merge extensions from a different type" userInfo:nil];
148 | }
149 |
150 | if (other.extensionMap.count > 0) {
151 | if (thisMessage.extensionMap == nil) {
152 | thisMessage.extensionMap = [NSMutableDictionary dictionary];
153 | }
154 |
155 | NSDictionary* registry = other.extensionRegistry;
156 | for (NSNumber* fieldNumber in other.extensionMap) {
157 | id thisField = [registry objectForKey:fieldNumber];
158 | id value = [other.extensionMap objectForKey:fieldNumber];
159 |
160 | if ([thisField isRepeated]) {
161 | NSMutableArray* list = [thisMessage.extensionMap objectForKey:fieldNumber];
162 | if (list == nil) {
163 | list = [NSMutableArray array];
164 | [thisMessage.extensionMap setObject:list forKey:fieldNumber];
165 | }
166 |
167 | [list addObjectsFromArray:value];
168 | } else {
169 | [thisMessage.extensionMap setObject:value forKey:fieldNumber];
170 | }
171 | }
172 | }
173 | }
174 |
175 | @end
176 |
--------------------------------------------------------------------------------
/GCDAsyncSocket/ProtobufBuffer/ExtensionField.h:
--------------------------------------------------------------------------------
1 | // Protocol Buffers for Objective C
2 | //
3 | // Copyright 2010 Booyah Inc.
4 | // Copyright 2008 Cyrus Najmabadi
5 | //
6 | // Licensed under the Apache License, Version 2.0 (the "License");
7 | // you may not use this file except in compliance with the License.
8 | // You may obtain a copy of the License at
9 | //
10 | // http://www.apache.org/licenses/LICENSE-2.0
11 | //
12 | // Unless required by applicable law or agreed to in writing, software
13 | // distributed under the License is distributed on an "AS IS" BASIS,
14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | // See the License for the specific language governing permissions and
16 | // limitations under the License.
17 |
18 | #import "WireFormat.h"
19 |
20 | @class PBCodedInputStream;
21 | @class PBCodedOutputStream;
22 | @class PBExtendableMessageBuilder;
23 | @class PBExtensionRegistry;
24 | @class PBUnknownFieldSetBuilder;
25 |
26 | @protocol PBExtensionField
27 | - (SInt32) fieldNumber;
28 | - (PBWireFormat) wireType;
29 | - (BOOL) isRepeated;
30 | - (Class) extendedClass;
31 | - (instancetype) defaultValue;
32 |
33 | - (void) mergeFromCodedInputStream:(PBCodedInputStream*) input
34 | unknownFields:(PBUnknownFieldSetBuilder*) unknownFields
35 | extensionRegistry:(PBExtensionRegistry*) extensionRegistry
36 | builder:(PBExtendableMessageBuilder*) builder
37 | tag:(SInt32) tag;
38 | - (void) writeValue:(id) value includingTagToCodedOutputStream:(PBCodedOutputStream*) output;
39 | - (SInt32) computeSerializedSizeIncludingTag:(id) value;
40 | - (void) writeDescriptionOf:(id) value
41 | to:(NSMutableString*) output
42 | withIndent:(NSString*) indent;
43 | - (void) addDictionaryEntriesOf:(id) value
44 | to:(NSMutableDictionary*) dictionary;
45 | @end
46 |
--------------------------------------------------------------------------------
/GCDAsyncSocket/ProtobufBuffer/ExtensionRegistry.h:
--------------------------------------------------------------------------------
1 | // Protocol Buffers for Objective C
2 | //
3 | // Copyright 2010 Booyah Inc.
4 | // Copyright 2008 Cyrus Najmabadi
5 | //
6 | // Licensed under the Apache License, Version 2.0 (the "License");
7 | // you may not use this file except in compliance with the License.
8 | // You may obtain a copy of the License at
9 | //
10 | // http://www.apache.org/licenses/LICENSE-2.0
11 | //
12 | // Unless required by applicable law or agreed to in writing, software
13 | // distributed under the License is distributed on an "AS IS" BASIS,
14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | // See the License for the specific language governing permissions and
16 | // limitations under the License.
17 |
18 | /**
19 | * A table of known extensions, searchable by name or field number. When
20 | * parsing a protocol message that might have extensions, you must provide
21 | * an {@code ExtensionRegistry} in which you have registered any extensions
22 | * that you want to be able to parse. Otherwise, those extensions will just
23 | * be treated like unknown fields.
24 | *
25 | * For example, if you had the {@code .proto} file:
26 | *
27 | *
28 | * option java_class = "MyProto";
29 | *
30 | * message Foo {
31 | * extensions 1000 to max;
32 | * }
33 | *
34 | * extend Foo {
35 | * optional int32 bar;
36 | * }
37 | *
38 | *
39 | * Then you might write code like:
40 | *
41 | *
42 | * ExtensionRegistry registry = ExtensionRegistry.newInstance();
43 | * registry.add(MyProto.bar);
44 | * MyProto.Foo message = MyProto.Foo.parseFrom(input, registry);
45 | *
46 | *
47 | * Background:
48 | *
49 | *
You might wonder why this is necessary. Two alternatives might come to
50 | * mind. First, you might imagine a system where generated extensions are
51 | * automatically registered when their containing classes are loaded. This
52 | * is a popular technique, but is bad design; among other things, it creates a
53 | * situation where behavior can change depending on what classes happen to be
54 | * loaded. It also introduces a security vulnerability, because an
55 | * unprivileged class could cause its code to be called unexpectedly from a
56 | * privileged class by registering itself as an extension of the right type.
57 | *
58 | *
Another option you might consider is lazy parsing: do not parse an
59 | * extension until it is first requested, at which point the caller must
60 | * provide a type to use. This introduces a different set of problems. First,
61 | * it would require a mutex lock any time an extension was accessed, which
62 | * would be slow. Second, corrupt data would not be detected until first
63 | * access, at which point it would be much harder to deal with it. Third, it
64 | * could violate the expectation that message objects are immutable, since the
65 | * type provided could be any arbitrary message class. An unpriviledged user
66 | * could take advantage of this to inject a mutable object into a message
67 | * belonging to priviledged code and create mischief.
68 | *
69 | * @author Cyrus Najmabadi
70 | */
71 |
72 | #import
73 | #import "ExtensionField.h"
74 |
75 | @interface PBExtensionRegistry : NSObject {
76 | @protected
77 | NSDictionary* classMap;
78 | }
79 |
80 | + (PBExtensionRegistry*) emptyRegistry;
81 | - (id) getExtension:(Class) clazz fieldNumber:(SInt32) fieldNumber;
82 |
83 | /* @protected */
84 | - (instancetype) initWithClassMap:(NSDictionary*) classMap;
85 | - (id) keyForClass:(Class) clazz;
86 |
87 | @end
88 |
--------------------------------------------------------------------------------
/GCDAsyncSocket/ProtobufBuffer/ExtensionRegistry.m:
--------------------------------------------------------------------------------
1 | // Protocol Buffers for Objective C
2 | //
3 | // Copyright 2010 Booyah Inc.
4 | // Copyright 2008 Cyrus Najmabadi
5 | //
6 | // Licensed under the Apache License, Version 2.0 (the "License");
7 | // you may not use this file except in compliance with the License.
8 | // You may obtain a copy of the License at
9 | //
10 | // http://www.apache.org/licenses/LICENSE-2.0
11 | //
12 | // Unless required by applicable law or agreed to in writing, software
13 | // distributed under the License is distributed on an "AS IS" BASIS,
14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | // See the License for the specific language governing permissions and
16 | // limitations under the License.
17 |
18 | #import "ExtensionRegistry.h"
19 |
20 | @interface PBExtensionRegistry()
21 | @property (strong) NSDictionary* classMap;
22 | @end
23 |
24 | @implementation PBExtensionRegistry
25 |
26 | @synthesize classMap;
27 |
28 |
29 | static PBExtensionRegistry* emptyRegistry = nil;
30 |
31 | + (void) initialize {
32 | if (self == [PBExtensionRegistry class]) {
33 | emptyRegistry = [[PBExtensionRegistry alloc] initWithClassMap:[NSDictionary dictionary]];
34 | }
35 | }
36 |
37 |
38 | - (instancetype) initWithClassMap:(NSDictionary*) map_{
39 | if ((self = [super init])) {
40 | self.classMap = map_;
41 | }
42 |
43 | return self;
44 | }
45 |
46 |
47 | - (id) keyForClass:(Class) clazz {
48 | return NSStringFromClass(clazz);
49 | }
50 |
51 |
52 | + (PBExtensionRegistry*) emptyRegistry {
53 | return emptyRegistry;
54 | }
55 |
56 |
57 | - (id) getExtension:(Class) clazz fieldNumber:(SInt32) fieldNumber {
58 | NSDictionary* extensionMap = [classMap objectForKey:[self keyForClass:clazz]];
59 | return [extensionMap objectForKey:[NSNumber numberWithInteger:fieldNumber]];
60 | }
61 |
62 | @end
63 |
--------------------------------------------------------------------------------
/GCDAsyncSocket/ProtobufBuffer/Field.h:
--------------------------------------------------------------------------------
1 | // Protocol Buffers for Objective C
2 | //
3 | // Copyright 2010 Booyah Inc.
4 | // Copyright 2008 Cyrus Najmabadi
5 | //
6 | // Licensed under the Apache License, Version 2.0 (the "License");
7 | // you may not use this file except in compliance with the License.
8 | // You may obtain a copy of the License at
9 | //
10 | // http://www.apache.org/licenses/LICENSE-2.0
11 | //
12 | // Unless required by applicable law or agreed to in writing, software
13 | // distributed under the License is distributed on an "AS IS" BASIS,
14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | // See the License for the specific language governing permissions and
16 | // limitations under the License.
17 |
18 | #import
19 |
20 | @class PBArray;
21 | @class PBAppendableArray;
22 | @class PBCodedOutputStream;
23 |
24 | @interface PBField : NSObject
25 | {
26 | @protected
27 | PBAppendableArray * _varintArray;
28 | PBAppendableArray * _fixed32Array;
29 | PBAppendableArray * _fixed64Array;
30 | NSMutableArray * _lengthDelimitedArray;
31 | NSMutableArray * _groupArray;
32 | }
33 |
34 | @property (nonatomic,strong,readonly) PBArray * varintArray;
35 | @property (nonatomic,strong,readonly) PBArray * fixed32Array;
36 | @property (nonatomic,strong,readonly) PBArray * fixed64Array;
37 | @property (nonatomic,strong,readonly) NSArray * lengthDelimitedArray;
38 | @property (nonatomic,strong,readonly) NSArray * groupArray;
39 |
40 | + (PBField *)defaultInstance;
41 |
42 | - (SInt32)getSerializedSize:(SInt32)fieldNumber;
43 | - (SInt32)getSerializedSizeAsMessageSetExtension:(SInt32)fieldNumber;
44 |
45 | - (void)writeTo:(SInt32) fieldNumber output:(PBCodedOutputStream *)output;
46 | - (void)writeAsMessageSetExtensionTo:(SInt32)fieldNumber output:(PBCodedOutputStream *)output;
47 | - (void)writeDescriptionFor:(SInt32) fieldNumber
48 | to:(NSMutableString*) output
49 | withIndent:(NSString*) indent;
50 | @end
51 |
--------------------------------------------------------------------------------
/GCDAsyncSocket/ProtobufBuffer/Field.m:
--------------------------------------------------------------------------------
1 | // Protocol Buffers for Objective C
2 | //
3 | // Copyright 2010 Booyah Inc.
4 | // Copyright 2008 Cyrus Najmabadi
5 | //
6 | // Licensed under the Apache License, Version 2.0 (the "License");
7 | // you may not use this file except in compliance with the License.
8 | // You may obtain a copy of the License at
9 | //
10 | // http://www.apache.org/licenses/LICENSE-2.0
11 | //
12 | // Unless required by applicable law or agreed to in writing, software
13 | // distributed under the License is distributed on an "AS IS" BASIS,
14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | // See the License for the specific language governing permissions and
16 | // limitations under the License.
17 |
18 | #import "Field.h"
19 |
20 | #import "CodedOutputStream.h"
21 | #import "PBArray.h"
22 | #import "UnknownFieldSet.h"
23 | #import "Utilities.h"
24 |
25 | @implementation PBField
26 |
27 | @synthesize varintArray = _varintArray;
28 | @synthesize fixed32Array = _fixed32Array;
29 | @synthesize fixed64Array = _fixed64Array;
30 | @synthesize lengthDelimitedArray = _lengthDelimitedArray;
31 | @synthesize groupArray = _groupArray;
32 |
33 | static PBField *sDefaultInstance = nil;
34 |
35 | + (void)initialize {
36 | if (self == [PBField class]) {
37 | sDefaultInstance = [[PBField alloc] init];
38 | }
39 | }
40 |
41 |
42 | + (PBField *)defaultInstance {
43 | return sDefaultInstance;
44 | }
45 |
46 | - (SInt32)getSerializedSize:(SInt32)fieldNumber {
47 | SInt32 result = 0;
48 |
49 | const SInt64 *varintValues = (const SInt64 *)_varintArray.data;
50 | if (varintValues) {
51 | const NSUInteger count = _varintArray.count;
52 | for (UInt32 i = 0; i < count; ++i) {
53 | result += computeInt64Size(fieldNumber, varintValues[i]);
54 | }
55 | }
56 |
57 | const SInt32 *fixed32Values = (const SInt32 *)_fixed32Array.data;
58 | if (fixed32Values) {
59 | const NSUInteger count = _fixed32Array.count;
60 | for (UInt32 i = 0; i < count; ++i) {
61 | result += computeFixed32Size(fieldNumber, fixed32Values[i]);
62 | }
63 | }
64 |
65 | const SInt64 *fixed64Values = (const SInt64 *)_fixed64Array.data;
66 | if (fixed64Values) {
67 | const NSUInteger count = _fixed64Array.count;
68 | for (NSUInteger i = 0; i < count; ++i) {
69 | result += computeFixed64Size(fieldNumber, fixed64Values[i]);
70 | }
71 | }
72 |
73 | for (NSData *value in _lengthDelimitedArray) {
74 | result += computeDataSize(fieldNumber, value);
75 | }
76 |
77 | for (PBUnknownFieldSet *value in _groupArray) {
78 | result += computeUnknownGroupSize(fieldNumber, value);
79 | }
80 |
81 | return result;
82 | }
83 |
84 | - (SInt32)getSerializedSizeAsMessageSetExtension:(SInt32)fieldNumber {
85 | SInt32 result = 0;
86 |
87 | for (NSData *value in _lengthDelimitedArray) {
88 | result += computeRawMessageSetExtensionSize(fieldNumber, value);
89 | }
90 |
91 | return result;
92 | }
93 |
94 | - (void)writeTo:(SInt32)fieldNumber output:(PBCodedOutputStream *) output {
95 | const SInt64 *varintValues = (const SInt64 *)_varintArray.data;
96 | if (varintValues) {
97 | const NSUInteger count = _varintArray.count;
98 | for (NSUInteger i = 0; i < count; ++i) {
99 | [output writeInt64:fieldNumber value:varintValues[i]];
100 | }
101 | }
102 |
103 | const SInt32 *fixed32Values = (const SInt32 *)_fixed32Array.data;
104 | if (fixed32Values) {
105 | const NSUInteger count = _fixed32Array.count;
106 | for (NSUInteger i = 0; i < count; ++i) {
107 | [output writeFixed32:fieldNumber value:fixed32Values[i]];
108 | }
109 | }
110 |
111 | const SInt64 *fixed64Values = (const SInt64 *)_fixed64Array.data;
112 | if (fixed64Values) {
113 | const NSUInteger count = _fixed64Array.count;
114 | for (NSUInteger i = 0; i < count; ++i) {
115 | [output writeFixed64:fieldNumber value:fixed64Values[i]];
116 | }
117 | }
118 |
119 | for (NSData *value in _lengthDelimitedArray) {
120 | [output writeData:fieldNumber value:value];
121 | }
122 |
123 | for (PBUnknownFieldSet *value in _groupArray) {
124 | [output writeUnknownGroup:fieldNumber value:value];
125 | }
126 | }
127 |
128 | - (void)writeDescriptionFor:(SInt32) fieldNumber
129 | to:(NSMutableString*) output
130 | withIndent:(NSString*) indent {
131 | [self.varintArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
132 |
133 | }];
134 | [self.varintArray enumerateObjectsUsingBlock:^(NSNumber* value, NSUInteger idx, BOOL *stop) {
135 | [output appendFormat:@"%@%ld: %qi\n", indent, (long)fieldNumber, value.longLongValue];
136 | }];
137 | [self.fixed32Array enumerateObjectsUsingBlock:^(NSNumber* value, NSUInteger idx, BOOL *stop) {
138 | [output appendFormat:@"%@%ld: %ld\n", indent, (long)fieldNumber, (long)value.integerValue];
139 | }];
140 | [self.fixed64Array enumerateObjectsUsingBlock:^(NSNumber* value, NSUInteger idx, BOOL *stop) {
141 | [output appendFormat:@"%@%ld: %lld\n", indent, (long)fieldNumber, value.longLongValue];
142 | }];
143 | for (NSData* value in self.lengthDelimitedArray) {
144 | [output appendFormat:@"%@%ld: %@\n", indent, (long)fieldNumber, value];
145 | }
146 | for (PBUnknownFieldSet* value in self.groupArray) {
147 | [output appendFormat:@"%@%ld: [\n", indent, (long)fieldNumber];
148 | [value writeDescriptionTo:output withIndent:[NSString stringWithFormat:@"%@ ", indent]];
149 | [output appendFormat:@"%@]", indent];
150 | }
151 | }
152 |
153 | - (void)writeAsMessageSetExtensionTo:(SInt32)fieldNumber output:(PBCodedOutputStream *) output {
154 | for (NSData *value in _lengthDelimitedArray) {
155 | [output writeRawMessageSetExtension:fieldNumber value:value];
156 | }
157 | }
158 |
159 | @end
--------------------------------------------------------------------------------
/GCDAsyncSocket/ProtobufBuffer/ForwardDeclarations.h:
--------------------------------------------------------------------------------
1 | // Protocol Buffers for Objective C
2 | //
3 | // Copyright 2010 Booyah Inc.
4 | // Copyright 2008 Cyrus Najmabadi
5 | //
6 | // Licensed under the Apache License, Version 2.0 (the "License");
7 | // you may not use this file except in compliance with the License.
8 | // You may obtain a copy of the License at
9 | //
10 | // http://www.apache.org/licenses/LICENSE-2.0
11 | //
12 | // Unless required by applicable law or agreed to in writing, software
13 | // distributed under the License is distributed on an "AS IS" BASIS,
14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | // See the License for the specific language governing permissions and
16 | // limitations under the License.
17 |
18 | @protocol PBMessage;
19 | @protocol PBMessageBuilder;
20 | @protocol PBExtensionField;
21 |
22 | @class PBAbstractMessage;
23 | @class PBCodedInputStream;
24 | @class PBCodedOutputStream;
25 | @class PBConcreteExtensionField;
26 | @class PBExtendableMessageBuilder;
27 | @class PBExtendableMessage;
28 | @class PBExtensionRegistry;
29 | @class PBField;
30 | @class PBGeneratedMessage;
31 | @class PBGeneratedMessageBuilder;
32 | @class PBMutableExtensionRegistry;
33 | @class PBMutableField;
34 | @class PBUnknownFieldSet;
35 | @class PBUnknownFieldSetBuilder;
36 |
--------------------------------------------------------------------------------
/GCDAsyncSocket/ProtobufBuffer/GeneratedMessage.h:
--------------------------------------------------------------------------------
1 | // Protocol Buffers for Objective C
2 | //
3 | // Copyright 2010 Booyah Inc.
4 | // Copyright 2008 Cyrus Najmabadi
5 | //
6 | // Licensed under the Apache License, Version 2.0 (the "License");
7 | // you may not use this file except in compliance with the License.
8 | // You may obtain a copy of the License at
9 | //
10 | // http://www.apache.org/licenses/LICENSE-2.0
11 | //
12 | // Unless required by applicable law or agreed to in writing, software
13 | // distributed under the License is distributed on an "AS IS" BASIS,
14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | // See the License for the specific language governing permissions and
16 | // limitations under the License.
17 |
18 | #import "AbstractMessage.h"
19 |
20 | /**
21 | * All generated protocol message classes extend this class. This class
22 | * implements most of the Message and Builder interfaces using Java reflection.
23 | * Users can ignore this class and pretend that generated messages implement
24 | * the Message interface directly.
25 | *
26 | * @author Cyrus Najmabadi
27 | */
28 | @class PBExtensionRegistry;
29 | @class PBCodedInputStream;
30 | @protocol GeneratedMessageProtocol
31 | + (id) parseFromData:(NSData*) data;
32 | + (id) parseFromData:(NSData*) data extensionRegistry:(PBExtensionRegistry*)extensionRegistry;
33 | + (id) parseFromInputStream:(NSInputStream*) input;
34 | + (id) parseFromInputStream:(NSInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
35 | + (id) parseFromCodedInputStream:(PBCodedInputStream*) input;
36 | + (id) parseFromCodedInputStream:(PBCodedInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
37 | @end
38 |
39 | @interface PBGeneratedMessage : PBAbstractMessage {
40 | @private
41 | PBUnknownFieldSet* unknownFields;
42 |
43 | @protected
44 | SInt32 memoizedSerializedSize;
45 | }
46 |
47 | @end
48 |
--------------------------------------------------------------------------------
/GCDAsyncSocket/ProtobufBuffer/GeneratedMessage.m:
--------------------------------------------------------------------------------
1 | // Protocol Buffers for Objective C
2 | //
3 | // Copyright 2010 Booyah Inc.
4 | // Copyright 2008 Cyrus Najmabadi
5 | //
6 | // Licensed under the Apache License, Version 2.0 (the "License");
7 | // you may not use this file except in compliance with the License.
8 | // You may obtain a copy of the License at
9 | //
10 | // http://www.apache.org/licenses/LICENSE-2.0
11 | //
12 | // Unless required by applicable law or agreed to in writing, software
13 | // distributed under the License is distributed on an "AS IS" BASIS,
14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | // See the License for the specific language governing permissions and
16 | // limitations under the License.
17 |
18 | #import "GeneratedMessage.h"
19 |
20 | #import "UnknownFieldSet.h"
21 |
22 | @interface PBGeneratedMessage ()
23 | @property (strong) PBUnknownFieldSet* unknownFields;
24 | @end
25 |
26 |
27 | @implementation PBGeneratedMessage
28 |
29 | @synthesize unknownFields;
30 |
31 | - (instancetype) init {
32 | if ((self = [super init])) {
33 | self.unknownFields = [PBUnknownFieldSet defaultInstance];
34 | memoizedSerializedSize = -1;
35 | }
36 |
37 | return self;
38 | }
39 |
40 | @end
41 |
--------------------------------------------------------------------------------
/GCDAsyncSocket/ProtobufBuffer/GeneratedMessageBuilder.h:
--------------------------------------------------------------------------------
1 | // Protocol Buffers for Objective C
2 | //
3 | // Copyright 2010 Booyah Inc.
4 | // Copyright 2008 Cyrus Najmabadi
5 | //
6 | // Licensed under the Apache License, Version 2.0 (the "License");
7 | // you may not use this file except in compliance with the License.
8 | // You may obtain a copy of the License at
9 | //
10 | // http://www.apache.org/licenses/LICENSE-2.0
11 | //
12 | // Unless required by applicable law or agreed to in writing, software
13 | // distributed under the License is distributed on an "AS IS" BASIS,
14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | // See the License for the specific language governing permissions and
16 | // limitations under the License.
17 |
18 | #import "AbstractMessageBuilder.h"
19 |
20 | @class PBUnknownFieldSetBuilder;
21 |
22 | @interface PBGeneratedMessageBuilder : PBAbstractMessageBuilder {
23 | }
24 |
25 | /* @protected */
26 | - (BOOL) parseUnknownField:(PBCodedInputStream*) input
27 | unknownFields:(PBUnknownFieldSetBuilder*) unknownFields
28 | extensionRegistry:(PBExtensionRegistry*) extensionRegistry
29 | tag:(SInt32) tag;
30 |
31 | - (void) checkInitialized;
32 |
33 | @end
34 |
--------------------------------------------------------------------------------
/GCDAsyncSocket/ProtobufBuffer/GeneratedMessageBuilder.m:
--------------------------------------------------------------------------------
1 | // Protocol Buffers for Objective C
2 | //
3 | // Copyright 2010 Booyah Inc.
4 | // Copyright 2008 Cyrus Najmabadi
5 | //
6 | // Licensed under the Apache License, Version 2.0 (the "License");
7 | // you may not use this file except in compliance with the License.
8 | // You may obtain a copy of the License at
9 | //
10 | // http://www.apache.org/licenses/LICENSE-2.0
11 | //
12 | // Unless required by applicable law or agreed to in writing, software
13 | // distributed under the License is distributed on an "AS IS" BASIS,
14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | // See the License for the specific language governing permissions and
16 | // limitations under the License.
17 |
18 | #import "GeneratedMessageBuilder.h"
19 |
20 | #import "GeneratedMessage.h"
21 | #import "Message.h"
22 | #import "MessageBuilder.h"
23 | #import "UnknownFieldSet.h"
24 | #import "UnknownFieldSetBuilder.h"
25 |
26 |
27 | @interface PBGeneratedMessage ()
28 | @property (strong) PBUnknownFieldSet* unknownFields;
29 | @end
30 |
31 |
32 | @implementation PBGeneratedMessageBuilder
33 |
34 | /**
35 | * Get the message being built. We don't just pass this to the
36 | * constructor because it becomes null when build() is called.
37 | */
38 | - (PBGeneratedMessage*) internalGetResult {
39 | @throw [NSException exceptionWithName:@"ImproperSubclassing" reason:@"" userInfo:nil];
40 | }
41 |
42 |
43 | - (void) checkInitialized {
44 | PBGeneratedMessage* result = self.internalGetResult;
45 | if (result != nil && !result.isInitialized) {
46 | @throw [NSException exceptionWithName:@"UninitializedMessage" reason:@"" userInfo:nil];
47 | }
48 | }
49 |
50 |
51 | - (PBUnknownFieldSet*) unknownFields {
52 | return self.internalGetResult.unknownFields;
53 | }
54 |
55 |
56 | - (id) setUnknownFields:(PBUnknownFieldSet*) unknownFields {
57 | self.internalGetResult.unknownFields = unknownFields;
58 | return self;
59 | }
60 |
61 |
62 | - (id) mergeUnknownFields:(PBUnknownFieldSet*) unknownFields {
63 | PBGeneratedMessage* result = self.internalGetResult;
64 | result.unknownFields =
65 | [[[PBUnknownFieldSet builderWithUnknownFields:result.unknownFields]
66 | mergeUnknownFields:unknownFields] build];
67 | return self;
68 | }
69 |
70 |
71 | - (BOOL) isInitialized {
72 | return self.internalGetResult.isInitialized;
73 | }
74 |
75 |
76 | /**
77 | * Called by subclasses to parse an unknown field.
78 | * @return {@code YES} unless the tag is an end-group tag.
79 | */
80 | - (BOOL) parseUnknownField:(PBCodedInputStream*) input
81 | unknownFields:(PBUnknownFieldSetBuilder*) unknownFields
82 | extensionRegistry:(PBExtensionRegistry*) extensionRegistry
83 | tag:(SInt32) tag {
84 | return [unknownFields mergeFieldFrom:tag input:input];
85 | }
86 |
87 |
88 | - (void) checkInitializedParsed {
89 | PBGeneratedMessage* result = self.internalGetResult;
90 | if (result != nil && !result.isInitialized) {
91 | @throw [NSException exceptionWithName:@"InvalidProtocolBuffer" reason:@"" userInfo:nil];
92 | }
93 | }
94 |
95 | @end
96 |
--------------------------------------------------------------------------------
/GCDAsyncSocket/ProtobufBuffer/Message.h:
--------------------------------------------------------------------------------
1 | // Protocol Buffers for Objective C
2 | //
3 | // Copyright 2010 Booyah Inc.
4 | // Copyright 2008 Cyrus Najmabadi
5 | //
6 | // Licensed under the Apache License, Version 2.0 (the "License");
7 | // you may not use this file except in compliance with the License.
8 | // You may obtain a copy of the License at
9 | //
10 | // http://www.apache.org/licenses/LICENSE-2.0
11 | //
12 | // Unless required by applicable law or agreed to in writing, software
13 | // distributed under the License is distributed on an "AS IS" BASIS,
14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | // See the License for the specific language governing permissions and
16 | // limitations under the License.
17 |
18 | #import
19 |
20 | @class PBCodedOutputStream;
21 | @class PBUnknownFieldSet;
22 | @protocol PBMessageBuilder;
23 |
24 | /**
25 | * Abstract interface implemented by Protocol Message objects.
26 | *
27 | * @author Cyrus Najmabadi
28 | */
29 | @protocol PBMessage
30 | /**
31 | * Get an instance of the type with all fields set to their default values.
32 | * This may or may not be a singleton. This differs from the
33 | * {@code getDefaultInstance()} method of generated message classes in that
34 | * this method is an abstract method of the {@code Message} interface
35 | * whereas {@code getDefaultInstance()} is a static method of a specific
36 | * class. They return the same thing.
37 | */
38 | - (id) defaultInstance;
39 |
40 | /**
41 | * Get the {@code UnknownFieldSet}
42 | */
43 | - (PBUnknownFieldSet*) unknownFields;
44 |
45 | /**
46 | * Get the number of bytes required to encode this message. The result
47 | * is only computed on the first call and memoized after that.
48 | */
49 | - (SInt32) serializedSize;
50 |
51 | /**
52 | * Returns true if all required fields in the message and all embedded
53 | * messages are set, false otherwise.
54 | */
55 | - (BOOL) isInitialized;
56 |
57 | /**
58 | * Serializes the message and writes it to {@code output}. This does not
59 | * flush or close the stream.
60 | */
61 | - (void) writeToCodedOutputStream:(PBCodedOutputStream*) output;
62 | - (void) writeToOutputStream:(NSOutputStream*) output;
63 |
64 | /**
65 | * Serializes the message to a {@code ByteString} and returns it. This is
66 | * just a trivial wrapper around
67 | * {@link #writeTo(CodedOutputStream)}.
68 | */
69 | - (NSData*) data;
70 |
71 | /**
72 | * Constructs a new builder for a message of the same type as this message.
73 | */
74 | - (id) builder;
75 |
76 | /**
77 | * Constructs a builder initialized with the current message. Use this to
78 | * derive a new message from the current one.
79 | */
80 | - (id) toBuilder;
81 |
82 | /**
83 | * Returns a string description of the message.
84 | */
85 | - (NSString*) description;
86 |
87 | @end
88 |
--------------------------------------------------------------------------------
/GCDAsyncSocket/ProtobufBuffer/MessageBuilder.h:
--------------------------------------------------------------------------------
1 | // Protocol Buffers for Objective C
2 | //
3 | // Copyright 2010 Booyah Inc.
4 | // Copyright 2008 Cyrus Najmabadi
5 | //
6 | // Licensed under the Apache License, Version 2.0 (the "License");
7 | // you may not use this file except in compliance with the License.
8 | // You may obtain a copy of the License at
9 | //
10 | // http://www.apache.org/licenses/LICENSE-2.0
11 | //
12 | // Unless required by applicable law or agreed to in writing, software
13 | // distributed under the License is distributed on an "AS IS" BASIS,
14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | // See the License for the specific language governing permissions and
16 | // limitations under the License.
17 |
18 | #import "Message.h"
19 |
20 | @class PBCodedInputStream;
21 | @class PBExtensionRegistry;
22 |
23 | /**
24 | * Abstract interface implemented by Protocol Message builders.
25 | */
26 | @protocol PBMessageBuilder
27 | /** Resets all fields to their default values. */
28 | - (id) clear;
29 |
30 | /**
31 | * Construct the final message. Once this is called, the Builder is no
32 | * longer valid, and calling any other method may throw a
33 | * NullPointerException. If you need to continue working with the builder
34 | * after calling {@code build()}, {@code clone()} it first.
35 | * @throws UninitializedMessageException The message is missing one or more
36 | * required fields (i.e. {@link #isInitialized()} returns false).
37 | * Use {@link #buildPartial()} to bypass this check.
38 | */
39 | - (id) build;
40 |
41 | /**
42 | * Like {@link #build()}, but does not throw an exception if the message
43 | * is missing required fields. Instead, a partial message is returned.
44 | */
45 | - (id) buildPartial;
46 | - (id) clone;
47 |
48 | /**
49 | * Returns true if all required fields in the message and all embedded
50 | * messages are set, false otherwise.
51 | */
52 | - (BOOL) isInitialized;
53 |
54 | /**
55 | * Get the message's type's default instance.
56 | * See {@link Message#getDefaultInstanceForType()}.
57 | */
58 | - (id) defaultInstance;
59 |
60 | - (PBUnknownFieldSet*) unknownFields;
61 | - (id) setUnknownFields:(PBUnknownFieldSet*) unknownFields;
62 |
63 | /**
64 | * Merge some unknown fields into the {@link UnknownFieldSet} for this
65 | * message.
66 | */
67 | - (id) mergeUnknownFields:(PBUnknownFieldSet*) unknownFields;
68 |
69 | /**
70 | * Parses a message of this type from the input and merges it with this
71 | * message, as if using {@link Builder#mergeFrom(Message)}.
72 | *
73 | * Warning: This does not verify that all required fields are present in
74 | * the input message. If you call {@link #build()} without setting all
75 | * required fields, it will throw an {@link UninitializedMessageException},
76 | * which is a {@code RuntimeException} and thus might not be caught. There
77 | * are a few good ways to deal with this:
78 | *
79 | * - Call {@link #isInitialized()} to verify that all required fields
80 | * are set before building.
81 | *
- Parse the message separately using one of the static
82 | * {@code parseFrom} methods, then use {@link #mergeFrom(Message)}
83 | * to merge it with this one. {@code parseFrom} will throw an
84 | * {@link InvalidProtocolBufferException} (an {@code IOException})
85 | * if some required fields are missing.
86 | *
- Use {@code buildPartial()} to build, which ignores missing
87 | * required fields.
88 | *
89 | *
90 | * Note: The caller should call
91 | * {@link CodedInputStream#checkLastTagWas(int)} after calling this to
92 | * verify that the last tag seen was the appropriate end-group tag,
93 | * or zero for EOF.
94 | */
95 | - (id) mergeFromCodedInputStream:(PBCodedInputStream*) input;
96 |
97 | /**
98 | * Like {@link Builder#mergeFrom(CodedInputStream)}, but also
99 | * parses extensions. The extensions that you want to be able to parse
100 | * must be registered in {@code extensionRegistry}. Extensions not in
101 | * the registry will be treated as unknown fields.
102 | */
103 | - (id) mergeFromCodedInputStream:(PBCodedInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
104 |
105 | /**
106 | * Parse {@code data} as a message of this type and merge it with the
107 | * message being built. This is just a small wrapper around
108 | * {@link #mergeFrom(CodedInputStream)}.
109 | */
110 | - (id) mergeFromData:(NSData*) data;
111 |
112 | /**
113 | * Parse {@code data} as a message of this type and merge it with the
114 | * message being built. This is just a small wrapper around
115 | * {@link #mergeFrom(CodedInputStream,ExtensionRegistry)}.
116 | */
117 | - (id) mergeFromData:(NSData*) data extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
118 |
119 | /**
120 | * Parse a message of this type from {@code input} and merge it with the
121 | * message being built. This is just a small wrapper around
122 | * {@link #mergeFrom(CodedInputStream)}. Note that this method always
123 | * reads the entire input (unless it throws an exception). If you
124 | * want it to stop earlier, you will need to wrap your input in some
125 | * wrapper stream that limits reading. Despite usually reading the entire
126 | * input, this does not close the stream.
127 | */
128 | - (id) mergeFromInputStream:(NSInputStream*) input;
129 |
130 | /**
131 | * Parse a message of this type from {@code input} and merge it with the
132 | * message being built. This is just a small wrapper around
133 | * {@link #mergeFrom(CodedInputStream,ExtensionRegistry)}.
134 | */
135 | - (id) mergeFromInputStream:(NSInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
136 | @end
137 |
--------------------------------------------------------------------------------
/GCDAsyncSocket/ProtobufBuffer/MutableExtensionRegistry.h:
--------------------------------------------------------------------------------
1 | // Protocol Buffers for Objective C
2 | //
3 | // Copyright 2010 Booyah Inc.
4 | // Copyright 2008 Cyrus Najmabadi
5 | //
6 | // Licensed under the Apache License, Version 2.0 (the "License");
7 | // you may not use this file except in compliance with the License.
8 | // You may obtain a copy of the License at
9 | //
10 | // http://www.apache.org/licenses/LICENSE-2.0
11 | //
12 | // Unless required by applicable law or agreed to in writing, software
13 | // distributed under the License is distributed on an "AS IS" BASIS,
14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | // See the License for the specific language governing permissions and
16 | // limitations under the License.
17 |
18 | #import "ExtensionRegistry.h"
19 |
20 | @interface PBMutableExtensionRegistry : PBExtensionRegistry {
21 | @private
22 | NSMutableDictionary* mutableClassMap;
23 | }
24 |
25 | + (PBMutableExtensionRegistry*) registry;
26 |
27 | - (void) addExtension:(id) extension;
28 |
29 | @end
30 |
--------------------------------------------------------------------------------
/GCDAsyncSocket/ProtobufBuffer/MutableExtensionRegistry.m:
--------------------------------------------------------------------------------
1 | // Protocol Buffers for Objective C
2 | //
3 | // Copyright 2010 Booyah Inc.
4 | // Copyright 2008 Cyrus Najmabadi
5 | //
6 | // Licensed under the Apache License, Version 2.0 (the "License");
7 | // you may not use this file except in compliance with the License.
8 | // You may obtain a copy of the License at
9 | //
10 | // http://www.apache.org/licenses/LICENSE-2.0
11 | //
12 | // Unless required by applicable law or agreed to in writing, software
13 | // distributed under the License is distributed on an "AS IS" BASIS,
14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | // See the License for the specific language governing permissions and
16 | // limitations under the License.
17 |
18 | #import "MutableExtensionRegistry.h"
19 |
20 | #import "ExtensionField.h"
21 |
22 | @interface PBMutableExtensionRegistry()
23 | @property (strong) NSMutableDictionary* mutableClassMap;
24 | @end
25 |
26 | @implementation PBMutableExtensionRegistry
27 |
28 | @synthesize mutableClassMap;
29 |
30 |
31 |
32 | - (instancetype) initWithClassMap:(NSMutableDictionary*) mutableClassMap_ {
33 | if ((self = [super initWithClassMap:mutableClassMap_])) {
34 | self.mutableClassMap = mutableClassMap_;
35 | }
36 |
37 | return self;
38 | }
39 |
40 |
41 | + (PBMutableExtensionRegistry*) registry {
42 | return [[PBMutableExtensionRegistry alloc] initWithClassMap:[NSMutableDictionary dictionary]];
43 | }
44 |
45 |
46 | - (void) addExtension:(id) extension {
47 | if (extension == nil) {
48 | return;
49 | }
50 |
51 | Class extendedClass = [extension extendedClass];
52 | id key = [self keyForClass:extendedClass];
53 |
54 | NSMutableDictionary* extensionMap = [classMap objectForKey:key];
55 | if (extensionMap == nil) {
56 | extensionMap = [NSMutableDictionary dictionary];
57 | [mutableClassMap setObject:extensionMap forKey:key];
58 | }
59 |
60 | [extensionMap setObject:extension
61 | forKey:[NSNumber numberWithInteger:[extension fieldNumber]]];
62 | }
63 |
64 |
65 | @end
66 |
--------------------------------------------------------------------------------
/GCDAsyncSocket/ProtobufBuffer/MutableField.h:
--------------------------------------------------------------------------------
1 | // Protocol Buffers for Objective C
2 | //
3 | // Copyright 2010 Booyah Inc.
4 | // Copyright 2008 Cyrus Najmabadi
5 | //
6 | // Licensed under the Apache License, Version 2.0 (the "License");
7 | // you may not use this file except in compliance with the License.
8 | // You may obtain a copy of the License at
9 | //
10 | // http://www.apache.org/licenses/LICENSE-2.0
11 | //
12 | // Unless required by applicable law or agreed to in writing, software
13 | // distributed under the License is distributed on an "AS IS" BASIS,
14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | // See the License for the specific language governing permissions and
16 | // limitations under the License.
17 |
18 | #import "Field.h"
19 |
20 | @class PBUnknownFieldSet;
21 |
22 | @interface PBMutableField : PBField
23 |
24 | + (PBMutableField *)field;
25 |
26 | - (PBMutableField *)mergeFromField:(PBField *)other;
27 |
28 | - (PBMutableField *)clear;
29 | - (PBMutableField *)addVarint:(SInt64)value;
30 | - (PBMutableField *)addFixed32:(SInt32)value;
31 | - (PBMutableField *)addFixed64:(SInt64)value;
32 | - (PBMutableField *)addLengthDelimited:(NSData *)value;
33 | - (PBMutableField *)addGroup:(PBUnknownFieldSet *)value;
34 |
35 | @end
--------------------------------------------------------------------------------
/GCDAsyncSocket/ProtobufBuffer/MutableField.m:
--------------------------------------------------------------------------------
1 | // Protocol Buffers for Objective C
2 | //
3 | // Copyright 2010 Booyah Inc.
4 | // Copyright 2008 Cyrus Najmabadi
5 | //
6 | // Licensed under the Apache License, Version 2.0 (the "License");
7 | // you may not use this file except in compliance with the License.
8 | // You may obtain a copy of the License at
9 | //
10 | // http://www.apache.org/licenses/LICENSE-2.0
11 | //
12 | // Unless required by applicable law or agreed to in writing, software
13 | // distributed under the License is distributed on an "AS IS" BASIS,
14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | // See the License for the specific language governing permissions and
16 | // limitations under the License.
17 |
18 | #import "MutableField.h"
19 |
20 | #import "Field.h"
21 | #import "PBArray.h"
22 |
23 | @implementation PBMutableField
24 |
25 |
26 | + (PBMutableField *)field {
27 | return [[PBMutableField alloc] init];
28 | }
29 |
30 | - (PBMutableField *)clear {
31 |
32 | _varintArray = nil;
33 | _fixed32Array = nil;
34 | _fixed64Array = nil;
35 | _lengthDelimitedArray = nil;
36 | _groupArray = nil;
37 |
38 | return self;
39 | }
40 |
41 | - (PBMutableField *)mergeFromField:(PBField *)other {
42 | if (other.varintArray.count > 0) {
43 | if (_varintArray == nil) {
44 | _varintArray = [other.varintArray copy];
45 | } else {
46 | [_varintArray appendArray:other.varintArray];
47 | }
48 | }
49 |
50 | if (other.fixed32Array.count > 0) {
51 | if (_fixed32Array == nil) {
52 | _fixed32Array = [other.fixed32Array copy];
53 | } else {
54 | [_fixed32Array appendArray:other.fixed32Array];
55 | }
56 | }
57 |
58 | if (other.fixed64Array.count > 0) {
59 | if (_fixed64Array == nil) {
60 | _fixed64Array = [other.fixed64Array copy];
61 | } else {
62 | [_fixed64Array appendArray:other.fixed64Array];
63 | }
64 | }
65 |
66 | if (other.lengthDelimitedArray.count > 0) {
67 | if (_lengthDelimitedArray == nil) {
68 | _lengthDelimitedArray = [other.lengthDelimitedArray mutableCopy];
69 | } else {
70 | [_lengthDelimitedArray addObjectsFromArray:other.lengthDelimitedArray];
71 | }
72 | }
73 |
74 | if (other.groupArray.count > 0) {
75 | if (_groupArray == nil) {
76 | _groupArray = [other.groupArray mutableCopy];
77 | } else {
78 | [_groupArray addObjectsFromArray:other.groupArray];
79 | }
80 | }
81 |
82 | return self;
83 | }
84 |
85 | - (PBMutableField *)addVarint:(SInt64)value {
86 | if (_varintArray == nil) {
87 | _varintArray = [[PBAppendableArray alloc] initWithValueType:PBArrayValueTypeInt64];
88 | }
89 | [_varintArray addInt64:value];
90 |
91 | return self;
92 | }
93 |
94 | - (PBMutableField *)addFixed32:(SInt32)value {
95 | if (_fixed32Array == nil) {
96 | _fixed32Array = [[PBAppendableArray alloc] initWithValueType:PBArrayValueTypeInt32];
97 | }
98 | [_fixed32Array addInt32:value];
99 |
100 | return self;
101 | }
102 |
103 | - (PBMutableField *)addFixed64:(SInt64)value {
104 | if (_fixed64Array == nil) {
105 | _fixed64Array = [[PBAppendableArray alloc] initWithValueType:PBArrayValueTypeInt64];
106 | }
107 | [_fixed64Array addInt64:value];
108 |
109 | return self;
110 | }
111 |
112 | - (PBMutableField *)addLengthDelimited:(NSData *)value {
113 | if (_lengthDelimitedArray == nil) {
114 | _lengthDelimitedArray = [[NSMutableArray alloc] init];
115 | }
116 | [_lengthDelimitedArray addObject:value];
117 |
118 | return self;
119 | }
120 |
121 | - (PBMutableField *)addGroup:(PBUnknownFieldSet *)value {
122 | if (_groupArray == nil) {
123 | _groupArray = [[NSMutableArray alloc] init];
124 | }
125 | [_groupArray addObject:value];
126 |
127 | return self;
128 | }
129 |
130 | @end
--------------------------------------------------------------------------------
/GCDAsyncSocket/ProtobufBuffer/ObjectivecDescriptor.pb.h:
--------------------------------------------------------------------------------
1 | // Generated by the protocol buffer compiler. DO NOT EDIT!
2 |
3 | #import "ProtocolBuffers.h"
4 |
5 | #import "Descriptor.pb.h"
6 | // @@protoc_insertion_point(imports)
7 |
8 | @class ObjectiveCFileOptions;
9 | @class ObjectiveCFileOptionsBuilder;
10 | @class PBDescriptorProto;
11 | @class PBDescriptorProtoBuilder;
12 | @class PBDescriptorProtoExtensionRange;
13 | @class PBDescriptorProtoExtensionRangeBuilder;
14 | @class PBEnumDescriptorProto;
15 | @class PBEnumDescriptorProtoBuilder;
16 | @class PBEnumOptions;
17 | @class PBEnumOptionsBuilder;
18 | @class PBEnumValueDescriptorProto;
19 | @class PBEnumValueDescriptorProtoBuilder;
20 | @class PBEnumValueOptions;
21 | @class PBEnumValueOptionsBuilder;
22 | @class PBFieldDescriptorProto;
23 | @class PBFieldDescriptorProtoBuilder;
24 | @class PBFieldOptions;
25 | @class PBFieldOptionsBuilder;
26 | @class PBFileDescriptorProto;
27 | @class PBFileDescriptorProtoBuilder;
28 | @class PBFileDescriptorSet;
29 | @class PBFileDescriptorSetBuilder;
30 | @class PBFileOptions;
31 | @class PBFileOptionsBuilder;
32 | @class PBMessageOptions;
33 | @class PBMessageOptionsBuilder;
34 | @class PBMethodDescriptorProto;
35 | @class PBMethodDescriptorProtoBuilder;
36 | @class PBMethodOptions;
37 | @class PBMethodOptionsBuilder;
38 | @class PBOneofDescriptorProto;
39 | @class PBOneofDescriptorProtoBuilder;
40 | @class PBServiceDescriptorProto;
41 | @class PBServiceDescriptorProtoBuilder;
42 | @class PBServiceOptions;
43 | @class PBServiceOptionsBuilder;
44 | @class PBSourceCodeInfo;
45 | @class PBSourceCodeInfoBuilder;
46 | @class PBSourceCodeInfoLocation;
47 | @class PBSourceCodeInfoLocationBuilder;
48 | @class PBUninterpretedOption;
49 | @class PBUninterpretedOptionBuilder;
50 | @class PBUninterpretedOptionNamePart;
51 | @class PBUninterpretedOptionNamePartBuilder;
52 |
53 |
54 |
55 | @interface ObjectivecDescriptorRoot : NSObject {
56 | }
57 | + (PBExtensionRegistry*) extensionRegistry;
58 | + (void) registerAllExtensions:(PBMutableExtensionRegistry*) registry;
59 | + (id) objectivecFileOptions;
60 | @end
61 |
62 | #define ObjectiveCFileOptions_package @"package"
63 | #define ObjectiveCFileOptions_class_prefix @"classPrefix"
64 | #define ObjectiveCFileOptions_relax_camel_case @"relaxCamelCase"
65 | @interface ObjectiveCFileOptions : PBGeneratedMessage {
66 | @private
67 | BOOL hasRelaxCamelCase_:1;
68 | BOOL hasPackage_:1;
69 | BOOL hasClassPrefix_:1;
70 | BOOL relaxCamelCase_:1;
71 | NSString* package;
72 | NSString* classPrefix;
73 | }
74 | - (BOOL) hasPackage;
75 | - (BOOL) hasClassPrefix;
76 | - (BOOL) hasRelaxCamelCase;
77 | @property (readonly, strong) NSString* package;
78 | @property (readonly, strong) NSString* classPrefix;
79 | - (BOOL) relaxCamelCase;
80 |
81 | + (instancetype) defaultInstance;
82 | - (instancetype) defaultInstance;
83 |
84 | - (BOOL) isInitialized;
85 | - (void) writeToCodedOutputStream:(PBCodedOutputStream*) output;
86 | - (ObjectiveCFileOptionsBuilder*) builder;
87 | + (ObjectiveCFileOptionsBuilder*) builder;
88 | + (ObjectiveCFileOptionsBuilder*) builderWithPrototype:(ObjectiveCFileOptions*) prototype;
89 | - (ObjectiveCFileOptionsBuilder*) toBuilder;
90 |
91 | + (ObjectiveCFileOptions*) parseFromData:(NSData*) data;
92 | + (ObjectiveCFileOptions*) parseFromData:(NSData*) data extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
93 | + (ObjectiveCFileOptions*) parseFromInputStream:(NSInputStream*) input;
94 | + (ObjectiveCFileOptions*) parseFromInputStream:(NSInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
95 | + (ObjectiveCFileOptions*) parseFromCodedInputStream:(PBCodedInputStream*) input;
96 | + (ObjectiveCFileOptions*) parseFromCodedInputStream:(PBCodedInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
97 | @end
98 |
99 | @interface ObjectiveCFileOptionsBuilder : PBGeneratedMessageBuilder {
100 | @private
101 | ObjectiveCFileOptions* resultObjectiveCfileOptions;
102 | }
103 |
104 | - (ObjectiveCFileOptions*) defaultInstance;
105 |
106 | - (ObjectiveCFileOptionsBuilder*) clear;
107 | - (ObjectiveCFileOptionsBuilder*) clone;
108 |
109 | - (ObjectiveCFileOptions*) build;
110 | - (ObjectiveCFileOptions*) buildPartial;
111 |
112 | - (ObjectiveCFileOptionsBuilder*) mergeFrom:(ObjectiveCFileOptions*) other;
113 | - (ObjectiveCFileOptionsBuilder*) mergeFromCodedInputStream:(PBCodedInputStream*) input;
114 | - (ObjectiveCFileOptionsBuilder*) mergeFromCodedInputStream:(PBCodedInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
115 |
116 | - (BOOL) hasPackage;
117 | - (NSString*) package;
118 | - (ObjectiveCFileOptionsBuilder*) setPackage:(NSString*) value;
119 | - (ObjectiveCFileOptionsBuilder*) clearPackage;
120 |
121 | - (BOOL) hasClassPrefix;
122 | - (NSString*) classPrefix;
123 | - (ObjectiveCFileOptionsBuilder*) setClassPrefix:(NSString*) value;
124 | - (ObjectiveCFileOptionsBuilder*) clearClassPrefix;
125 |
126 | - (BOOL) hasRelaxCamelCase;
127 | - (BOOL) relaxCamelCase;
128 | - (ObjectiveCFileOptionsBuilder*) setRelaxCamelCase:(BOOL) value;
129 | - (ObjectiveCFileOptionsBuilder*) clearRelaxCamelCase;
130 | @end
131 |
132 |
133 | // @@protoc_insertion_point(global_scope)
134 |
--------------------------------------------------------------------------------
/GCDAsyncSocket/ProtobufBuffer/PBArray.h:
--------------------------------------------------------------------------------
1 | // Protocol Buffers for Objective C
2 | //
3 | // Copyright 2010 Booyah Inc.
4 | //
5 | // Licensed under the Apache License, Version 2.0 (the "License");
6 | // you may not use this file except in compliance with the License.
7 | // You may obtain a copy of the License at
8 | //
9 | // http://www.apache.org/licenses/LICENSE-2.0
10 | //
11 | // Unless required by applicable law or agreed to in writing, software
12 | // distributed under the License is distributed on an "AS IS" BASIS,
13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | // See the License for the specific language governing permissions and
15 | // limitations under the License.
16 | //
17 | // Author: Jon Parise
18 |
19 | #import
20 |
21 | extern NSString * const PBArrayTypeMismatchException;
22 | extern NSString * const PBArrayNumberExpectedException;
23 | extern NSString * const PBArrayAllocationFailureException;
24 |
25 | typedef enum _PBArrayValueType
26 | {
27 | PBArrayValueTypeBool,
28 | PBArrayValueTypeInt32,
29 | PBArrayValueTypeUInt32,
30 | PBArrayValueTypeInt64,
31 | PBArrayValueTypeUInt64,
32 | PBArrayValueTypeFloat,
33 | PBArrayValueTypeDouble,
34 | } PBArrayValueType;
35 |
36 | // PBArray is an immutable array class that's optimized for storing primitive
37 | // values. All values stored in an PBArray instance must have the same type
38 | // (PBArrayValueType). Object values (PBArrayValueTypeObject) are retained.
39 | @interface PBArray : NSObject
40 | {
41 | @protected
42 | PBArrayValueType _valueType;
43 | NSUInteger _capacity;
44 | NSUInteger _count;
45 | void * _data;
46 |
47 | }
48 |
49 | - (NSUInteger)count;
50 | - (BOOL)boolAtIndex:(NSUInteger)index;
51 | - (SInt32)int32AtIndex:(NSUInteger)index;
52 | - (SInt32)enumAtIndex:(NSUInteger)index;
53 | - (UInt32)uint32AtIndex:(NSUInteger)index;
54 | - (SInt64)int64AtIndex:(NSUInteger)index;
55 | - (UInt64)uint64AtIndex:(NSUInteger)index;
56 | - (Float32)floatAtIndex:(NSUInteger)index;
57 | - (Float64)doubleAtIndex:(NSUInteger)index;
58 | - (BOOL)isEqualToArray:(PBArray *)array;
59 | - (void)enumerateObjectsUsingBlock:(void (^)(id obj, NSUInteger idx, BOOL *stop))block;
60 | - (NSUInteger)indexOfObjectPassingTest:(BOOL (^)(id obj, NSUInteger idx, BOOL *stop))predicate;
61 |
62 | //This Methods automaticaly pack/unpack in NSNumber primitive values
63 | - (id)firstObject;
64 | - (id)lastObject;
65 | - (id)objectAtIndexedSubscript:(NSUInteger)idx;
66 |
67 | @property (nonatomic,assign,readonly) PBArrayValueType valueType;
68 | @property (nonatomic,assign,readonly) const void * data;
69 | @property (nonatomic,assign,readonly,getter=count) NSUInteger count;
70 |
71 | @end
72 |
73 | @interface PBArray (PBArrayExtended)
74 |
75 | - (instancetype)arrayByAppendingArray:(PBArray *)array;
76 | - (PBArray *)filteredArrayUsingPredicate:(NSPredicate *)predicate;
77 | @end
78 |
79 | @interface PBArray (PBArrayCreation)
80 |
81 | + (instancetype)arrayWithValueType:(PBArrayValueType)valueType;
82 | + (instancetype)arrayWithValues:(const void *)values count:(NSUInteger)count valueType:(PBArrayValueType)valueType;
83 | + (instancetype)arrayWithArray:(NSArray *)array valueType:(PBArrayValueType)valueType;
84 | - (instancetype)initWithValueType:(PBArrayValueType)valueType;
85 | - (instancetype)initWithValues:(const void *)values count:(NSUInteger)count valueType:(PBArrayValueType)valueType;
86 | - (instancetype)initWithArray:(NSArray *)array valueType:(PBArrayValueType)valueType;
87 |
88 | @end
89 |
90 | // PBAppendableArray extends PBArray with the ability to append new values to
91 | // the end of the array.
92 | @interface PBAppendableArray : PBArray
93 |
94 | - (void)addBool:(BOOL)value;
95 | - (void)addInt32:(SInt32)value;
96 | - (void)addUint32:(UInt32)value;
97 | - (void)addInt64:(SInt64)value;
98 | - (void)addUint64:(UInt64)value;
99 | - (void)addFloat:(Float32)value;
100 | - (void)addDouble:(Float64)value;
101 | - (void)addEnum:(SInt32)value;
102 |
103 | - (void)appendArray:(PBArray *)array;
104 | - (void)appendValues:(const void *)values count:(UInt32)count;
105 |
106 | @end
107 |
--------------------------------------------------------------------------------
/GCDAsyncSocket/ProtobufBuffer/ProtocolBuffers.h:
--------------------------------------------------------------------------------
1 | // Protocol Buffers for Objective C
2 | //
3 | // Copyright 2010 Booyah Inc.
4 | // Copyright 2008 Cyrus Najmabadi
5 | //
6 | // Licensed under the Apache License, Version 2.0 (the "License");
7 | // you may not use this file except in compliance with the License.
8 | // You may obtain a copy of the License at
9 | //
10 | // http://www.apache.org/licenses/LICENSE-2.0
11 | //
12 | // Unless required by applicable law or agreed to in writing, software
13 | // distributed under the License is distributed on an "AS IS" BASIS,
14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | // See the License for the specific language governing permissions and
16 | // limitations under the License.
17 |
18 | #import
19 |
20 | #import "Bootstrap.h"
21 | #import "AbstractMessage.h"
22 | #import "AbstractMessageBuilder.h"
23 | #import "CodedInputStream.h"
24 | #import "CodedOutputStream.h"
25 | #import "ConcreteExtensionField.h"
26 | #import "ExtendableMessage.h"
27 | #import "ExtendableMessageBuilder.h"
28 | #import "ExtensionField.h"
29 | #import "ExtensionRegistry.h"
30 | #import "Field.h"
31 | #import "GeneratedMessage.h"
32 | #import "GeneratedMessageBuilder.h"
33 | #import "Message.h"
34 | #import "MessageBuilder.h"
35 | #import "MutableExtensionRegistry.h"
36 | #import "MutableField.h"
37 | #import "PBArray.h"
38 | #import "UnknownFieldSet.h"
39 | #import "UnknownFieldSetBuilder.h"
40 | #import "Utilities.h"
41 | #import "WireFormat.h"
42 | #import "Descriptor.pb.h"
43 | #import "ObjectivecDescriptor.pb.h"
44 |
--------------------------------------------------------------------------------
/GCDAsyncSocket/ProtobufBuffer/RingBuffer.h:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | @interface RingBuffer : NSObject {
4 | NSMutableData *buffer;
5 | SInt32 position;
6 | SInt32 tail;
7 | }
8 | @property (nonatomic, readonly) UInt32 freeSpace;
9 |
10 | - (instancetype)initWithData:(NSMutableData*)data;
11 |
12 | // Returns false if there is not enough free space in buffer
13 | - (BOOL)appendByte:(uint8_t)byte;
14 |
15 | // Returns number of bytes written
16 | - (SInt32)appendData:(const NSData*)value offset:(SInt32)offset length:(SInt32)length;
17 |
18 | // Returns number of bytes written
19 | - (SInt32)flushToOutputStream:(NSOutputStream*)stream;
20 |
21 | @end
22 |
--------------------------------------------------------------------------------
/GCDAsyncSocket/ProtobufBuffer/RingBuffer.m:
--------------------------------------------------------------------------------
1 | #import "RingBuffer.h"
2 |
3 | @implementation RingBuffer
4 |
5 | - (instancetype)initWithData:(NSMutableData*)data {
6 | if ((self = [super init])) {
7 | buffer = data;
8 | }
9 | return self;
10 | }
11 |
12 |
13 | - (UInt32)freeSpace {
14 | return (UInt32)(position < tail ? tail - position : (buffer.length - position) + tail) - (tail ? 1 : 0);
15 | }
16 |
17 |
18 | - (BOOL)appendByte:(uint8_t)byte {
19 | if (self.freeSpace < 1) return NO;
20 | ((uint8_t*)buffer.mutableBytes)[position++] = byte;
21 | return YES;
22 | }
23 |
24 |
25 | - (SInt32)appendData:(const NSData*)value offset:(SInt32)offset length:(SInt32)length {
26 | SInt32 totalWritten = 0;
27 | const uint8_t *input = value.bytes;
28 | uint8_t *data = buffer.mutableBytes;
29 |
30 | if (position >= tail) {
31 | totalWritten = MIN((UInt32)buffer.length - position, length);
32 | memcpy(data + position, input + offset, totalWritten);
33 | position += totalWritten;
34 | if (totalWritten == length) return length;
35 | length -= totalWritten;
36 | offset += totalWritten;
37 | }
38 |
39 | UInt32 freeSpace = self.freeSpace;
40 | if (!freeSpace) return totalWritten;
41 |
42 | if (position == buffer.length) {
43 | position = 0;
44 | }
45 |
46 | // position < tail
47 | SInt32 written = MIN(freeSpace, length);
48 | memcpy(data + position, input + offset, written);
49 | position += written;
50 | totalWritten += written;
51 |
52 | return totalWritten;
53 | }
54 |
55 |
56 | - (SInt32)flushToOutputStream:(NSOutputStream*)stream {
57 | SInt32 totalWritten = 0;
58 | const uint8_t *data = buffer.bytes;
59 |
60 | if (tail > position) {
61 | SInt32 written = (SInt32)[stream write:data + tail maxLength:buffer.length - tail];
62 | if (written <= 0) return totalWritten;
63 | totalWritten += written;
64 | tail += written;
65 | if (tail == buffer.length) {
66 | tail = 0;
67 | }
68 | }
69 |
70 | if (tail < position) {
71 | SInt32 written = (SInt32)[stream write:data + tail maxLength:position - tail];
72 | if (written <= 0) return totalWritten;
73 | totalWritten += written;
74 | tail += written;
75 | }
76 |
77 | if (tail == position) {
78 | tail = position = 0;
79 | }
80 |
81 | if (position == buffer.length && tail > 0) {
82 | position = 0;
83 | }
84 |
85 | if (tail == buffer.length) {
86 | tail = 0;
87 | }
88 |
89 | return totalWritten;
90 | }
91 |
92 | @end
93 |
--------------------------------------------------------------------------------
/GCDAsyncSocket/ProtobufBuffer/TextFormat.h:
--------------------------------------------------------------------------------
1 | // Protocol Buffers for Objective C
2 | //
3 | // Copyright 2010 Booyah Inc.
4 | // Copyright 2008 Cyrus Najmabadi
5 | //
6 | // Licensed under the Apache License, Version 2.0 (the "License");
7 | // you may not use this file except in compliance with the License.
8 | // You may obtain a copy of the License at
9 | //
10 | // http://www.apache.org/licenses/LICENSE-2.0
11 | //
12 | // Unless required by applicable law or agreed to in writing, software
13 | // distributed under the License is distributed on an "AS IS" BASIS,
14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | // See the License for the specific language governing permissions and
16 | // limitations under the License.
17 |
18 | #import
19 |
20 | @interface PBTextFormat : NSObject {
21 |
22 | }
23 |
24 | + (SInt32) parseInt32:(NSString*) text;
25 | + (SInt32) parseUInt32:(NSString*) text;
26 | + (SInt64) parseInt64:(NSString*) text;
27 | + (SInt64) parseUInt64:(NSString*) text;
28 |
29 | + (NSData*) unescapeBytes:(NSString*) input;
30 |
31 | @end
32 |
--------------------------------------------------------------------------------
/GCDAsyncSocket/ProtobufBuffer/TextFormat.m:
--------------------------------------------------------------------------------
1 | // Protocol Buffers for Objective C
2 | //
3 | // Copyright 2010 Booyah Inc.
4 | // Copyright 2008 Cyrus Najmabadi
5 | //
6 | // Licensed under the Apache License, Version 2.0 (the "License");
7 | // you may not use this file except in compliance with the License.
8 | // You may obtain a copy of the License at
9 | //
10 | // http://www.apache.org/licenses/LICENSE-2.0
11 | //
12 | // Unless required by applicable law or agreed to in writing, software
13 | // distributed under the License is distributed on an "AS IS" BASIS,
14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | // See the License for the specific language governing permissions and
16 | // limitations under the License.
17 |
18 | #import "TextFormat.h"
19 |
20 | #import "Utilities.h"
21 |
22 | @implementation PBTextFormat
23 |
24 |
25 | BOOL allZeroes(NSString* string) {
26 | for (int i = 0; i < string.length; i++) {
27 | if ([string characterAtIndex:i] != '0') {
28 | return NO;
29 | }
30 | }
31 |
32 | return YES;
33 | }
34 |
35 |
36 | /** Is this an octal digit? */
37 | BOOL isOctal(unichar c) {
38 | return '0' <= c && c <= '7';
39 | }
40 |
41 |
42 | /** Is this an octal digit? */
43 | BOOL isDecimal(unichar c) {
44 | return '0' <= c && c <= '9';
45 | }
46 |
47 | /** Is this a hex digit? */
48 | BOOL isHex(unichar c) {
49 | return
50 | isDecimal(c) ||
51 | ('a' <= c && c <= 'f') ||
52 | ('A' <= c && c <= 'F');
53 | }
54 |
55 |
56 | + (SInt64) parseInteger:(NSString*) text
57 | isSigned:(BOOL) isSigned
58 | isLong:(BOOL) isLong {
59 | if (text.length == 0) {
60 | @throw [NSException exceptionWithName:@"NumberFormat" reason:@"Number was blank" userInfo:nil];
61 | }
62 |
63 | if (isblank([text characterAtIndex:0])) {
64 | @throw [NSException exceptionWithName:@"NumberFormat" reason:@"Invalid character" userInfo:nil];
65 | }
66 |
67 | if ([text hasPrefix:@"-"]) {
68 | if (!isSigned) {
69 | @throw [NSException exceptionWithName:@"NumberFormat" reason:@"Number must be positive" userInfo:nil];
70 | }
71 | }
72 |
73 | // now call into the appropriate conversion utilities.
74 | SInt64 result;
75 | const char* in_string = text.UTF8String;
76 | char* out_string = NULL;
77 | errno = 0;
78 | if (isLong) {
79 | if (isSigned) {
80 | result = strtoll(in_string, &out_string, 0);
81 | } else {
82 | result = convertUInt64ToInt64(strtoull(in_string, &out_string, 0));
83 | }
84 | } else {
85 | if (isSigned) {
86 | result = strtol(in_string, &out_string, 0);
87 | } else {
88 | result = convertUInt32ToInt32((SInt32)strtoul(in_string, &out_string, 0));
89 | }
90 | }
91 |
92 | // from the man pages:
93 | // (Thus, i* tr is not `\0' but **endptr is `\0' on return, the entire
94 | // string was valid.)
95 | if (*in_string == 0 || *out_string != 0) {
96 | @throw [NSException exceptionWithName:@"NumberFormat" reason:@"IllegalNumber" userInfo:nil];
97 | }
98 |
99 | if (errno == ERANGE) {
100 | @throw [NSException exceptionWithName:@"NumberFormat" reason:@"Number out of range" userInfo:nil];
101 | }
102 |
103 | return result;
104 | }
105 |
106 |
107 | /**
108 | * Parse a 32-bit signed integer from the text. This function recognizes
109 | * the prefixes "0x" and "0" to signify hexidecimal and octal numbers,
110 | * respectively.
111 | */
112 | + (SInt32) parseInt32:(NSString*) text {
113 | return (SInt32)[self parseInteger:text isSigned:YES isLong:NO];
114 | }
115 |
116 |
117 | /**
118 | * Parse a 32-bit unsigned integer from the text. This function recognizes
119 | * the prefixes "0x" and "0" to signify hexidecimal and octal numbers,
120 | * respectively. The result is coerced to a (signed) {@code int} when returned.
121 | */
122 | + (SInt32) parseUInt32:(NSString*) text {
123 | return (SInt32)[self parseInteger:text isSigned:NO isLong:NO];
124 | }
125 |
126 |
127 | /**
128 | * Parse a 64-bit signed integer from the text. This function recognizes
129 | * the prefixes "0x" and "0" to signify hexidecimal and octal numbers,
130 | * respectively.
131 | */
132 | + (SInt64) parseInt64:(NSString*) text {
133 | return [self parseInteger:text isSigned:YES isLong:YES];
134 | }
135 |
136 |
137 | /**
138 | * Parse a 64-bit unsigned integer from the text. This function recognizes
139 | * the prefixes "0x" and "0" to signify hexidecimal and octal numbers,
140 | * respectively. The result is coerced to a (signed) {@code SInt32} when
141 | * returned.
142 | */
143 | + (SInt64) parseUInt64:(NSString*) text {
144 | return [self parseInteger:text isSigned:NO isLong:YES];
145 | }
146 |
147 | /**
148 | * Interpret a character as a digit (in any base up to 36) and return the
149 | * numeric value. This is like {@code Character.digit()} but we don't accept
150 | * non-ASCII digits.
151 | */
152 | SInt32 digitValue(unichar c) {
153 | if ('0' <= c && c <= '9') {
154 | return c - '0';
155 | } else if ('a' <= c && c <= 'z') {
156 | return c - 'a' + 10;
157 | } else {
158 | return c - 'A' + 10;
159 | }
160 | }
161 |
162 |
163 | /**
164 | * Un-escape a byte sequence as escaped using
165 | * {@link #escapeBytes(ByteString)}. Two-digit hex escapes (starting with
166 | * "\x") are also recognized.
167 | */
168 | + (NSData*) unescapeBytes:(NSString*) input {
169 | NSMutableData* result = [NSMutableData dataWithLength:input.length];
170 |
171 | SInt32 pos = 0;
172 | for (SInt32 i = 0; i < input.length; i++) {
173 | unichar c = [input characterAtIndex:i];
174 | if (c == '\\') {
175 | if (i + 1 < input.length) {
176 | ++i;
177 | c = [input characterAtIndex:i];
178 | if (isOctal(c)) {
179 | // Octal escape.
180 | SInt32 code = digitValue(c);
181 | if (i + 1 < input.length && isOctal([input characterAtIndex:(i + 1)])) {
182 | ++i;
183 | code = code * 8 + digitValue([input characterAtIndex:i]);
184 | }
185 | if (i + 1 < input.length && isOctal([input characterAtIndex:(i + 1)])) {
186 | ++i;
187 | code = code * 8 + digitValue([input characterAtIndex:i]);
188 | }
189 | ((int8_t*)result.mutableBytes)[pos++] = (int8_t)code;
190 | } else {
191 | switch (c) {
192 | case 'a' : ((int8_t*)result.mutableBytes)[pos++] = 0x07; break;
193 | case 'b' : ((int8_t*)result.mutableBytes)[pos++] = '\b'; break;
194 | case 'f' : ((int8_t*)result.mutableBytes)[pos++] = '\f'; break;
195 | case 'n' : ((int8_t*)result.mutableBytes)[pos++] = '\n'; break;
196 | case 'r' : ((int8_t*)result.mutableBytes)[pos++] = '\r'; break;
197 | case 't' : ((int8_t*)result.mutableBytes)[pos++] = '\t'; break;
198 | case 'v' : ((int8_t*)result.mutableBytes)[pos++] = 0x0b; break;
199 | case '\\': ((int8_t*)result.mutableBytes)[pos++] = '\\'; break;
200 | case '\'': ((int8_t*)result.mutableBytes)[pos++] = '\''; break;
201 | case '"' : ((int8_t*)result.mutableBytes)[pos++] = '\"'; break;
202 |
203 | case 'x': // hex escape
204 | {
205 | SInt32 code = 0;
206 | if (i + 1 < input.length && isHex([input characterAtIndex:(i + 1)])) {
207 | ++i;
208 | code = digitValue([input characterAtIndex:i]);
209 | } else {
210 | @throw [NSException exceptionWithName:@"InvalidEscape" reason:@"Invalid escape sequence: '\\x' with no digits" userInfo:nil];
211 | }
212 | if (i + 1 < input.length && isHex([input characterAtIndex:(i + 1)])) {
213 | ++i;
214 | code = code * 16 + digitValue([input characterAtIndex:i]);
215 | }
216 | ((int8_t*)result.mutableBytes)[pos++] = (int8_t)code;
217 | break;
218 | }
219 |
220 | default:
221 | @throw [NSException exceptionWithName:@"InvalidEscape" reason:@"Invalid escape sequence" userInfo:nil];
222 | }
223 | }
224 | } else {
225 | @throw [NSException exceptionWithName:@"InvalidEscape" reason:@"Invalid escape sequence: '\\' at end of string" userInfo:nil];
226 | }
227 | } else {
228 | ((int8_t*)result.mutableBytes)[pos++] = (int8_t)c;
229 | }
230 | }
231 |
232 | [result setLength:pos];
233 | return result;
234 | }
235 |
236 | @end
237 |
--------------------------------------------------------------------------------
/GCDAsyncSocket/ProtobufBuffer/UnknownFieldSet.h:
--------------------------------------------------------------------------------
1 | // Protocol Buffers for Objective C
2 | //
3 | // Copyright 2010 Booyah Inc.
4 | // Copyright 2008 Cyrus Najmabadi
5 | //
6 | // Licensed under the Apache License, Version 2.0 (the "License");
7 | // you may not use this file except in compliance with the License.
8 | // You may obtain a copy of the License at
9 | //
10 | // http://www.apache.org/licenses/LICENSE-2.0
11 | //
12 | // Unless required by applicable law or agreed to in writing, software
13 | // distributed under the License is distributed on an "AS IS" BASIS,
14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | // See the License for the specific language governing permissions and
16 | // limitations under the License.
17 | #import
18 |
19 | @class PBCodedOutputStream;
20 | @class PBField;
21 | @class PBUnknownFieldSetBuilder;
22 |
23 | @interface PBUnknownFieldSet : NSObject {
24 | @private
25 | NSDictionary* fields;
26 | }
27 |
28 | @property (readonly, strong) NSDictionary* fields;
29 |
30 | + (PBUnknownFieldSet*) defaultInstance;
31 |
32 | + (PBUnknownFieldSet*) setWithFields:(NSMutableDictionary*) fields;
33 | + (PBUnknownFieldSet*) parseFromData:(NSData*) data;
34 |
35 | + (PBUnknownFieldSetBuilder*) builder;
36 | + (PBUnknownFieldSetBuilder*) builderWithUnknownFields:(PBUnknownFieldSet*) other;
37 |
38 | - (void) writeAsMessageSetTo:(PBCodedOutputStream*) output;
39 | - (void) writeToCodedOutputStream:(PBCodedOutputStream*) output;
40 | - (NSData*) data;
41 |
42 | - (SInt32) serializedSize;
43 | - (SInt32) serializedSizeAsMessageSet;
44 |
45 | - (BOOL) hasField:(SInt32) number;
46 | - (PBField*) getField:(SInt32) number;
47 |
48 | - (void) writeDescriptionTo:(NSMutableString*) output
49 | withIndent:(NSString*) indent;
50 |
51 | - (void) storeInDictionary: (NSMutableDictionary *) dic;
52 |
53 | @end
54 |
--------------------------------------------------------------------------------
/GCDAsyncSocket/ProtobufBuffer/UnknownFieldSet.m:
--------------------------------------------------------------------------------
1 | // Protocol Buffers for Objective C
2 | //
3 | // Copyright 2010 Booyah Inc.
4 | // Copyright 2008 Cyrus Najmabadi
5 | //
6 | // Licensed under the Apache License, Version 2.0 (the "License");
7 | // you may not use this file except in compliance with the License.
8 | // You may obtain a copy of the License at
9 | //
10 | // http://www.apache.org/licenses/LICENSE-2.0
11 | //
12 | // Unless required by applicable law or agreed to in writing, software
13 | // distributed under the License is distributed on an "AS IS" BASIS,
14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | // See the License for the specific language governing permissions and
16 | // limitations under the License.
17 |
18 | #import "UnknownFieldSet.h"
19 |
20 | #import "CodedInputStream.h"
21 | #import "CodedOutputStream.h"
22 | #import "Field.h"
23 | #import "UnknownFieldSetBuilder.h"
24 |
25 | @interface PBUnknownFieldSet()
26 | @property (strong) NSDictionary* fields;
27 | @end
28 |
29 |
30 | @implementation PBUnknownFieldSet
31 |
32 | static PBUnknownFieldSet* defaultInstance = nil;
33 |
34 | + (void) initialize {
35 | if (self == [PBUnknownFieldSet class]) {
36 | defaultInstance = [PBUnknownFieldSet setWithFields:[NSMutableDictionary dictionary]];
37 | }
38 | }
39 |
40 |
41 | @synthesize fields;
42 |
43 |
44 |
45 |
46 | + (PBUnknownFieldSet*) defaultInstance {
47 | return defaultInstance;
48 | }
49 |
50 |
51 | - (instancetype) initWithFields:(NSMutableDictionary*) fields_ {
52 | if ((self = [super init])) {
53 | self.fields = fields_;
54 | }
55 |
56 | return self;
57 | }
58 |
59 |
60 | + (PBUnknownFieldSet*) setWithFields:(NSMutableDictionary*) fields {
61 | return [[PBUnknownFieldSet alloc] initWithFields:fields];
62 | }
63 |
64 |
65 | - (BOOL) hasField:(SInt32) number {
66 | return [fields objectForKey:@(number)] != nil;
67 | }
68 |
69 |
70 | - (PBField*) getField:(SInt32) number {
71 | PBField* result = [fields objectForKey:@(number)];
72 | return (result == nil) ? [PBField defaultInstance] : result;
73 | }
74 |
75 |
76 | - (void) writeToCodedOutputStream:(PBCodedOutputStream*) output {
77 | NSArray* sortedKeys = [fields.allKeys sortedArrayUsingSelector:@selector(compare:)];
78 | for (NSNumber* number in sortedKeys) {
79 | PBField* value = [fields objectForKey:number];
80 | [value writeTo:(SInt32)number.integerValue output:output];
81 | }
82 | }
83 |
84 |
85 | - (void) writeToOutputStream:(NSOutputStream*) output {
86 | PBCodedOutputStream* codedOutput = [PBCodedOutputStream streamWithOutputStream:output];
87 | [self writeToCodedOutputStream:codedOutput];
88 | [codedOutput flush];
89 | }
90 |
91 |
92 | - (void) writeDescriptionTo:(NSMutableString*) output
93 | withIndent:(NSString *)indent {
94 | NSArray* sortedKeys = [fields.allKeys sortedArrayUsingSelector:@selector(compare:)];
95 | for (NSNumber* number in sortedKeys) {
96 | PBField* value = [fields objectForKey:number];
97 | [value writeDescriptionFor:(SInt32)number.integerValue to:output withIndent:indent];
98 | }
99 | }
100 |
101 | - (void) storeInDictionary: (NSMutableDictionary *) dic;
102 | {
103 | //TODO: Ignore unknown field sets for now :D
104 | }
105 |
106 | + (PBUnknownFieldSet*) parseFromCodedInputStream:(PBCodedInputStream*) input {
107 | return [[[PBUnknownFieldSet builder] mergeFromCodedInputStream:input] build];
108 | }
109 |
110 |
111 | + (PBUnknownFieldSet*) parseFromData:(NSData*) data {
112 | return [[[PBUnknownFieldSet builder] mergeFromData:data] build];
113 | }
114 |
115 |
116 | + (PBUnknownFieldSet*) parseFromInputStream:(NSInputStream*) input {
117 | return [[[PBUnknownFieldSet builder] mergeFromInputStream:input] build];
118 | }
119 |
120 |
121 | + (PBUnknownFieldSetBuilder*) builder {
122 | return [[PBUnknownFieldSetBuilder alloc] init];
123 | }
124 |
125 |
126 | + (PBUnknownFieldSetBuilder*) builderWithUnknownFields:(PBUnknownFieldSet*) copyFrom {
127 | return [[PBUnknownFieldSet builder] mergeUnknownFields:copyFrom];
128 | }
129 |
130 |
131 | /** Get the number of bytes required to encode this set. */
132 | - (SInt32) serializedSize {
133 | SInt32 result = 0;
134 | for (NSNumber* number in fields) {
135 | result += [[fields objectForKey:number] getSerializedSize:(SInt32)number.integerValue];
136 | }
137 | return result;
138 | }
139 |
140 | /**
141 | * Serializes the set and writes it to {@code output} using
142 | * {@code MessageSet} wire format.
143 | */
144 | - (void) writeAsMessageSetTo:(PBCodedOutputStream*) output {
145 | for (NSNumber* number in fields) {
146 | [[fields objectForKey:number] writeAsMessageSetExtensionTo:(SInt32)number.integerValue output:output];
147 | }
148 | }
149 |
150 |
151 | /**
152 | * Get the number of bytes required to encode this set using
153 | * {@code MessageSet} wire format.
154 | */
155 | - (SInt32) serializedSizeAsMessageSet {
156 | SInt32 result = 0;
157 | for (NSNumber* number in fields) {
158 | result += [[fields objectForKey:number] getSerializedSizeAsMessageSetExtension:(SInt32)number.integerValue];
159 | }
160 | return result;
161 | }
162 |
163 |
164 | /**
165 | * Serializes the message to a {@code ByteString} and returns it. This is
166 | * just a trivial wrapper around {@link #writeTo(PBCodedOutputStream)}.
167 | */
168 | - (NSData*) data {
169 | NSMutableData* data = [NSMutableData dataWithLength:self.serializedSize];
170 | PBCodedOutputStream* output = [PBCodedOutputStream streamWithData:data];
171 |
172 | [self writeToCodedOutputStream:output];
173 | return data;
174 | }
175 |
176 | @end
177 |
--------------------------------------------------------------------------------
/GCDAsyncSocket/ProtobufBuffer/UnknownFieldSetBuilder.h:
--------------------------------------------------------------------------------
1 | // Protocol Buffers for Objective C
2 | //
3 | // Copyright 2010 Booyah Inc.
4 | // Copyright 2008 Cyrus Najmabadi
5 | //
6 | // Licensed under the Apache License, Version 2.0 (the "License");
7 | // you may not use this file except in compliance with the License.
8 | // You may obtain a copy of the License at
9 | //
10 | // http://www.apache.org/licenses/LICENSE-2.0
11 | //
12 | // Unless required by applicable law or agreed to in writing, software
13 | // distributed under the License is distributed on an "AS IS" BASIS,
14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | // See the License for the specific language governing permissions and
16 | // limitations under the License.
17 |
18 | #import "MessageBuilder.h"
19 |
20 | @class PBField;
21 | @class PBMutableField;
22 |
23 | @interface PBUnknownFieldSetBuilder : NSObject {
24 | @private
25 | NSMutableDictionary* fields;
26 |
27 | // Optimization: We keep around a builder for the last field that was
28 | // modified so that we can efficiently add to it multiple times in a
29 | // row (important when parsing an unknown repeated field).
30 | SInt32 lastFieldNumber;
31 |
32 | PBMutableField* lastField;
33 | }
34 |
35 | + (PBUnknownFieldSetBuilder*) createBuilder:(PBUnknownFieldSet*) unknownFields;
36 |
37 | - (PBUnknownFieldSet*) build;
38 | - (PBUnknownFieldSetBuilder*) mergeUnknownFields:(PBUnknownFieldSet*) other;
39 |
40 | - (PBUnknownFieldSetBuilder*) mergeFromCodedInputStream:(PBCodedInputStream*) input;
41 | - (PBUnknownFieldSetBuilder*) mergeFromData:(NSData*) data;
42 | - (PBUnknownFieldSetBuilder*) mergeFromInputStream:(NSInputStream*) input;
43 |
44 | - (PBUnknownFieldSetBuilder*) mergeVarintField:(SInt32) number value:(SInt32) value;
45 |
46 | - (BOOL) mergeFieldFrom:(SInt32) tag input:(PBCodedInputStream*) input;
47 |
48 | - (PBUnknownFieldSetBuilder*) addField:(PBField*) field forNumber:(SInt32) number;
49 |
50 | - (PBUnknownFieldSetBuilder*) clear;
51 | - (PBUnknownFieldSetBuilder*) mergeField:(PBField*) field forNumber:(SInt32) number;
52 |
53 | @end
54 |
--------------------------------------------------------------------------------
/GCDAsyncSocket/ProtobufBuffer/UnknownFieldSetBuilder.m:
--------------------------------------------------------------------------------
1 | // Protocol Buffers for Objective C
2 | //
3 | // Copyright 2010 Booyah Inc.
4 | // Copyright 2008 Cyrus Najmabadi
5 | //
6 | // Licensed under the Apache License, Version 2.0 (the "License");
7 | // you may not use this file except in compliance with the License.
8 | // You may obtain a copy of the License at
9 | //
10 | // http://www.apache.org/licenses/LICENSE-2.0
11 | //
12 | // Unless required by applicable law or agreed to in writing, software
13 | // distributed under the License is distributed on an "AS IS" BASIS,
14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | // See the License for the specific language governing permissions and
16 | // limitations under the License.
17 |
18 | #import "UnknownFieldSetBuilder.h"
19 |
20 | #import "CodedInputStream.h"
21 | #import "Field.h"
22 | #import "MutableField.h"
23 | #import "UnknownFieldSet.h"
24 | #import "WireFormat.h"
25 |
26 | @interface PBUnknownFieldSetBuilder ()
27 | @property (strong) NSMutableDictionary* fields;
28 | @property SInt32 lastFieldNumber;
29 | @property (strong) PBMutableField* lastField;
30 | @end
31 |
32 |
33 | @implementation PBUnknownFieldSetBuilder
34 |
35 | @synthesize fields;
36 | @synthesize lastFieldNumber;
37 | @synthesize lastField;
38 |
39 |
40 | - (instancetype) init {
41 | if ((self = [super init])) {
42 | self.fields = [NSMutableDictionary dictionary];
43 | }
44 | return self;
45 | }
46 |
47 |
48 | + (PBUnknownFieldSetBuilder*) createBuilder:(PBUnknownFieldSet*) unknownFields {
49 | PBUnknownFieldSetBuilder* builder = [[PBUnknownFieldSetBuilder alloc] init];
50 | [builder mergeUnknownFields:unknownFields];
51 | return builder;
52 | }
53 |
54 |
55 | /**
56 | * Add a field to the {@code PBUnknownFieldSet}. If a field with the same
57 | * number already exists, it is removed.
58 | */
59 | - (PBUnknownFieldSetBuilder*) addField:(PBField*) field forNumber:(SInt32) number {
60 | if (number == 0) {
61 | @throw [NSException exceptionWithName:@"IllegalArgument" reason:@"" userInfo:nil];
62 | }
63 | if (lastField != nil && lastFieldNumber == number) {
64 | // Discard this.
65 | self.lastField = nil;
66 | lastFieldNumber = 0;
67 | }
68 | [fields setObject:field forKey:@(number)];
69 | return self;
70 | }
71 |
72 |
73 | /**
74 | * Get a field builder for the given field number which includes any
75 | * values that already exist.
76 | */
77 | - (PBMutableField*) getFieldBuilder:(SInt32) number {
78 | if (lastField != nil) {
79 | if (number == lastFieldNumber) {
80 | return lastField;
81 | }
82 | // Note: addField() will reset lastField and lastFieldNumber.
83 | [self addField:lastField forNumber:lastFieldNumber];
84 | }
85 | if (number == 0) {
86 | return nil;
87 | } else {
88 | PBField* existing = [fields objectForKey:@(number)];
89 | lastFieldNumber = number;
90 | self.lastField = [PBMutableField field];
91 | if (existing != nil) {
92 | [lastField mergeFromField:existing];
93 | }
94 | return lastField;
95 | }
96 | }
97 |
98 |
99 | - (PBUnknownFieldSet*) build {
100 | [self getFieldBuilder:0]; // Force lastField to be built.
101 | PBUnknownFieldSet* result;
102 | if (fields.count == 0) {
103 | result = [PBUnknownFieldSet defaultInstance];
104 | } else {
105 | result = [PBUnknownFieldSet setWithFields:fields];
106 | }
107 | self.fields = nil;
108 | return result;
109 | }
110 |
111 | - (PBUnknownFieldSet*) buildPartial {
112 | @throw [NSException exceptionWithName:@"UnsupportedMethod" reason:@"" userInfo:nil];
113 | }
114 |
115 | - (PBUnknownFieldSet*) clone {
116 | @throw [NSException exceptionWithName:@"UnsupportedMethod" reason:@"" userInfo:nil];
117 | }
118 |
119 | - (BOOL) isInitialized {
120 | return YES;
121 | }
122 |
123 | - (PBUnknownFieldSet*) defaultInstance {
124 | @throw [NSException exceptionWithName:@"UnsupportedMethod" reason:@"" userInfo:nil];
125 | }
126 |
127 | - (PBUnknownFieldSet*) unknownFields {
128 | return [self build];
129 | }
130 |
131 | - (id) setUnknownFields:(PBUnknownFieldSet*) unknownFields {
132 | @throw [NSException exceptionWithName:@"UnsupportedMethod" reason:@"" userInfo:nil];
133 | }
134 |
135 | /** Check if the given field number is present in the set. */
136 | - (BOOL) hasField:(SInt32) number {
137 | if (number == 0) {
138 | @throw [NSException exceptionWithName:@"IllegalArgument" reason:@"" userInfo:nil];
139 | }
140 |
141 | return number == lastFieldNumber || ([fields objectForKey:@(number)] != nil);
142 | }
143 |
144 |
145 | /**
146 | * Add a field to the {@code PBUnknownFieldSet}. If a field with the same
147 | * number already exists, the two are merged.
148 | */
149 | - (PBUnknownFieldSetBuilder*) mergeField:(PBField*) field forNumber:(SInt32) number {
150 | if (number == 0) {
151 | @throw [NSException exceptionWithName:@"IllegalArgument" reason:@"" userInfo:nil];
152 | }
153 | if ([self hasField:number]) {
154 | [[self getFieldBuilder:number] mergeFromField:field];
155 | } else {
156 | // Optimization: We could call getFieldBuilder(number).mergeFrom(field)
157 | // in this case, but that would create a copy of the PBField object.
158 | // We'd rather reuse the one passed to us, so call addField() instead.
159 | [self addField:field forNumber:number];
160 | }
161 |
162 | return self;
163 | }
164 |
165 |
166 | - (PBUnknownFieldSetBuilder*) mergeUnknownFields:(PBUnknownFieldSet*) other {
167 | if (other != [PBUnknownFieldSet defaultInstance]) {
168 | for (NSNumber* number in other.fields) {
169 | PBField* field = [other.fields objectForKey:number];
170 | [self mergeField:field forNumber:(SInt32)[number integerValue]];
171 | }
172 | }
173 | return self;
174 | }
175 |
176 |
177 | - (PBUnknownFieldSetBuilder*) mergeFromData:(NSData*) data {
178 | PBCodedInputStream* input = [PBCodedInputStream streamWithData:data];
179 | [self mergeFromCodedInputStream:input];
180 | [input checkLastTagWas:0];
181 | return self;
182 | }
183 |
184 |
185 | - (PBUnknownFieldSetBuilder*) mergeFromData:(NSData*) data extensionRegistry:(PBExtensionRegistry*) extensionRegistry {
186 | PBCodedInputStream* input = [PBCodedInputStream streamWithData:data];
187 | [self mergeFromCodedInputStream:input extensionRegistry:extensionRegistry];
188 | [input checkLastTagWas:0];
189 | return self;
190 | }
191 |
192 |
193 | - (PBUnknownFieldSetBuilder*) mergeFromInputStream:(NSInputStream*) input {
194 | @throw [NSException exceptionWithName:@"UnsupportedMethod" reason:@"" userInfo:nil];
195 | }
196 |
197 | - (PBUnknownFieldSetBuilder*) mergeFromInputStream:(NSInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry {
198 | @throw [NSException exceptionWithName:@"UnsupportedMethod" reason:@"" userInfo:nil];
199 | }
200 |
201 | - (PBUnknownFieldSetBuilder*) mergeVarintField:(SInt32) number value:(SInt32) value {
202 | if (number == 0) {
203 | @throw [NSException exceptionWithName:@"IllegalArgument" reason:@"Zero is not a valid field number." userInfo:nil];
204 | }
205 |
206 | [[self getFieldBuilder:number] addVarint:value];
207 | return self;
208 | }
209 |
210 |
211 | /**
212 | * Parse a single field from {@code input} and merge it into this set.
213 | * @param tag The field's tag number, which was already parsed.
214 | * @return {@code NO} if the tag is an engroup tag.
215 | */
216 | - (BOOL) mergeFieldFrom:(SInt32) tag input:(PBCodedInputStream*) input {
217 | SInt32 number = PBWireFormatGetTagFieldNumber(tag);
218 | switch (PBWireFormatGetTagWireType(tag)) {
219 | case PBWireFormatVarint:
220 | [[self getFieldBuilder:number] addVarint:[input readInt64]];
221 | return YES;
222 | case PBWireFormatFixed64:
223 | [[self getFieldBuilder:number] addFixed64:[input readFixed64]];
224 | return YES;
225 | case PBWireFormatLengthDelimited:
226 | [[self getFieldBuilder:number] addLengthDelimited:[input readData]];
227 | return YES;
228 | case PBWireFormatStartGroup: {
229 | PBUnknownFieldSetBuilder* subBuilder = [PBUnknownFieldSet builder];
230 | [input readUnknownGroup:number builder:subBuilder];
231 | [[self getFieldBuilder:number] addGroup:[subBuilder build]];
232 | return YES;
233 | }
234 | case PBWireFormatEndGroup:
235 | return NO;
236 | case PBWireFormatFixed32:
237 | [[self getFieldBuilder:number] addFixed32:[input readFixed32]];
238 | return YES;
239 | default:
240 | @throw [NSException exceptionWithName:@"InvalidProtocolBuffer" reason:@"" userInfo:nil];
241 | }
242 | }
243 |
244 |
245 | /**
246 | * Parse an entire message from {@code input} and merge its fields into
247 | * this set.
248 | */
249 | - (PBUnknownFieldSetBuilder*) mergeFromCodedInputStream:(PBCodedInputStream*) input {
250 | while (YES) {
251 | SInt32 tag = [input readTag];
252 | if (tag == 0 || ![self mergeFieldFrom:tag input:input]) {
253 | break;
254 | }
255 | }
256 | return self;
257 | }
258 |
259 | - (PBUnknownFieldSetBuilder*) mergeFromCodedInputStream:(PBCodedInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry {
260 | @throw [NSException exceptionWithName:@"UnsupportedMethod" reason:@"" userInfo:nil];
261 | }
262 |
263 | - (PBUnknownFieldSetBuilder*) clear {
264 | self.fields = [NSMutableDictionary dictionary];
265 | self.lastFieldNumber = 0;
266 | self.lastField = nil;
267 | return self;
268 | }
269 |
270 | @end
271 |
--------------------------------------------------------------------------------
/GCDAsyncSocket/ProtobufBuffer/Utilities.h:
--------------------------------------------------------------------------------
1 | // Protocol Buffers for Objective C
2 | //
3 | // Copyright 2010 Booyah Inc.
4 | // Copyright 2008 Cyrus Najmabadi
5 | //
6 | // Licensed under the Apache License, Version 2.0 (the "License");
7 | // you may not use this file except in compliance with the License.
8 | // You may obtain a copy of the License at
9 | //
10 | // http://www.apache.org/licenses/LICENSE-2.0
11 | //
12 | // Unless required by applicable law or agreed to in writing, software
13 | // distributed under the License is distributed on an "AS IS" BASIS,
14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | // See the License for the specific language governing permissions and
16 | // limitations under the License.
17 |
18 | #import "Message.h"
19 |
20 | SInt64 convertFloat64ToInt64(Float64 f);
21 | SInt32 convertFloat32ToInt32(Float32 f);
22 | Float64 convertInt64ToFloat64(SInt64 f);
23 | Float32 convertInt32ToFloat32(SInt32 f);
24 |
25 | UInt64 convertInt64ToUInt64(SInt64 i);
26 | SInt64 convertUInt64ToInt64(UInt64 u);
27 | UInt32 convertInt32ToUInt32(SInt32 i);
28 | SInt32 convertUInt32ToInt32(UInt32 u);
29 |
30 | SInt32 logicalRightShift32(SInt32 value, SInt32 spaces);
31 | SInt64 logicalRightShift64(SInt64 value, SInt32 spaces);
32 |
33 |
34 | /**
35 | * Decode a ZigZag-encoded 32-bit value. ZigZag encodes signed integers
36 | * into values that can be efficiently encoded with varint. (Otherwise,
37 | * negative values must be sign-extended to 64 bits to be varint encoded,
38 | * thus always taking 10 bytes on the wire.)
39 | *
40 | * @param n An unsigned 32-bit integer, stored in a signed int.
41 | * @return A signed 32-bit integer.
42 | */
43 | SInt32 decodeZigZag32(SInt32 n);
44 |
45 | /**
46 | * Decode a ZigZag-encoded 64-bit value. ZigZag encodes signed integers
47 | * into values that can be efficiently encoded with varint. (Otherwise,
48 | * negative values must be sign-extended to 64 bits to be varint encoded,
49 | * thus always taking 10 bytes on the wire.)
50 | *
51 | * @param n An unsigned 64-bit integer, stored in a signed int.
52 | * @return A signed 64-bit integer.
53 | */
54 | SInt64 decodeZigZag64(SInt64 n);
55 |
56 |
57 | /**
58 | * Encode a ZigZag-encoded 32-bit value. ZigZag encodes signed integers
59 | * into values that can be efficiently encoded with varint. (Otherwise,
60 | * negative values must be sign-extended to 64 bits to be varint encoded,
61 | * thus always taking 10 bytes on the wire.)
62 | *
63 | * @param n A signed 32-bit integer.
64 | * @return An unsigned 32-bit integer, stored in a signed int.
65 | */
66 | SInt32 encodeZigZag32(SInt32 n);
67 |
68 | /**
69 | * Encode a ZigZag-encoded 64-bit value. ZigZag encodes signed integers
70 | * into values that can be efficiently encoded with varint. (Otherwise,
71 | * negative values must be sign-extended to 64 bits to be varint encoded,
72 | * thus always taking 10 bytes on the wire.)
73 | *
74 | * @param n A signed 64-bit integer.
75 | * @return An unsigned 64-bit integer, stored in a signed int.
76 | */
77 | SInt64 encodeZigZag64(SInt64 n);
78 |
79 | /**
80 | * Compute the number of bytes that would be needed to encode a
81 | * {@code double} field, including tag.
82 | */
83 | SInt32 computeDoubleSize(SInt32 fieldNumber, Float64 value);
84 |
85 | /**
86 | * Compute the number of bytes that would be needed to encode a
87 | * {@code float} field, including tag.
88 | */
89 | SInt32 computeFloatSize(SInt32 fieldNumber, Float32 value);
90 |
91 | /**
92 | * Compute the number of bytes that would be needed to encode a
93 | * {@code uint64} field, including tag.
94 | */
95 | SInt32 computeUInt64Size(SInt32 fieldNumber, SInt64 value);
96 |
97 | /**
98 | * Compute the number of bytes that would be needed to encode an
99 | * {@code int64} field, including tag.
100 | */
101 | SInt32 computeInt64Size(SInt32 fieldNumber, SInt64 value);
102 |
103 | /**
104 | * Compute the number of bytes that would be needed to encode an
105 | * {@code int32} field, including tag.
106 | */
107 | SInt32 computeInt32Size(SInt32 fieldNumber, SInt32 value);
108 |
109 | /**
110 | * Compute the number of bytes that would be needed to encode a
111 | * {@code fixed64} field, including tag.
112 | */
113 | SInt32 computeFixed64Size(SInt32 fieldNumber, SInt64 value);
114 |
115 | /**
116 | * Compute the number of bytes that would be needed to encode a
117 | * {@code fixed32} field, including tag.
118 | */
119 | SInt32 computeFixed32Size(SInt32 fieldNumber, SInt32 value);
120 |
121 | /**
122 | * Compute the number of bytes that would be needed to encode a
123 | * {@code bool} field, including tag.
124 | */
125 | SInt32 computeBoolSize(SInt32 fieldNumber, BOOL value);
126 |
127 | /**
128 | * Compute the number of bytes that would be needed to encode a
129 | * {@code string} field, including tag.
130 | */
131 | SInt32 computeStringSize(SInt32 fieldNumber, const NSString* value);
132 |
133 | /**
134 | * Compute the number of bytes that would be needed to encode a
135 | * {@code group} field, including tag.
136 | */
137 | SInt32 computeGroupSize(SInt32 fieldNumber, const id value);
138 |
139 | /**
140 | * Compute the number of bytes that would be needed to encode a
141 | * {@code group} field represented by an {@code PBUnknownFieldSet}, including
142 | * tag.
143 | */
144 | SInt32 computeUnknownGroupSize(SInt32 fieldNumber, const PBUnknownFieldSet* value);
145 |
146 | /**
147 | * Compute the number of bytes that would be needed to encode an
148 | * embedded message field, including tag.
149 | */
150 | SInt32 computeMessageSize(SInt32 fieldNumber, const id value);
151 |
152 | /**
153 | * Compute the number of bytes that would be needed to encode a
154 | * {@code bytes} field, including tag.
155 | */
156 | SInt32 computeDataSize(SInt32 fieldNumber, const NSData* value);
157 |
158 | /**
159 | * Compute the number of bytes that would be needed to encode a
160 | * {@code uint32} field, including tag.
161 | */
162 | SInt32 computeUInt32Size(SInt32 fieldNumber, SInt32 value);
163 |
164 | /**
165 | * Compute the number of bytes that would be needed to encode an
166 | * {@code sfixed32} field, including tag.
167 | */
168 | SInt32 computeSFixed32Size(SInt32 fieldNumber, SInt32 value);
169 |
170 | /**
171 | * Compute the number of bytes that would be needed to encode an
172 | * {@code sfixed64} field, including tag.
173 | */
174 | SInt32 computeSFixed64Size(SInt32 fieldNumber, SInt64 value);
175 |
176 | /**
177 | * Compute the number of bytes that would be needed to encode an
178 | * {@code sint32} field, including tag.
179 | */
180 | SInt32 computeSInt32Size(SInt32 fieldNumber, SInt32 value);
181 |
182 | /**
183 | * Compute the number of bytes that would be needed to encode an
184 | * {@code sint64} field, including tag.
185 | */
186 | SInt32 computeSInt64Size(SInt32 fieldNumber, SInt64 value);
187 |
188 | /** Compute the number of bytes that would be needed to encode a tag. */
189 | SInt32 computeTagSize(SInt32 fieldNumber);
190 |
191 | /**
192 | * Compute the number of bytes that would be needed to encode a
193 | * {@code double} field, including tag.
194 | */
195 | SInt32 computeDoubleSizeNoTag(Float64 value);
196 |
197 | /**
198 | * Compute the number of bytes that would be needed to encode a
199 | * {@code float} field, including tag.
200 | */
201 | SInt32 computeFloatSizeNoTag(Float32 value);
202 |
203 | /**
204 | * Compute the number of bytes that would be needed to encode a
205 | * {@code uint64} field, including tag.
206 | */
207 | SInt32 computeUInt64SizeNoTag(SInt64 value);
208 |
209 | /**
210 | * Compute the number of bytes that would be needed to encode an
211 | * {@code int64} field, including tag.
212 | */
213 | SInt32 computeInt64SizeNoTag(SInt64 value);
214 | /**
215 | * Compute the number of bytes that would be needed to encode an
216 | * {@code int32} field, including tag.
217 | */
218 | SInt32 computeInt32SizeNoTag(SInt32 value);
219 |
220 | /**
221 | * Compute the number of bytes that would be needed to encode a
222 | * {@code fixed64} field, including tag.
223 | */
224 | SInt32 computeFixed64SizeNoTag(SInt64 value);
225 |
226 | /**
227 | * Compute the number of bytes that would be needed to encode a
228 | * {@code fixed32} field, including tag.
229 | */
230 | SInt32 computeFixed32SizeNoTag(SInt32 value);
231 |
232 | /**
233 | * Compute the number of bytes that would be needed to encode a
234 | * {@code bool} field, including tag.
235 | */
236 | SInt32 computeBoolSizeNoTag(BOOL value);
237 |
238 | /**
239 | * Compute the number of bytes that would be needed to encode a
240 | * {@code string} field, including tag.
241 | */
242 | SInt32 computeStringSizeNoTag(const NSString* value);
243 |
244 | /**
245 | * Compute the number of bytes that would be needed to encode a
246 | * {@code group} field, including tag.
247 | */
248 | SInt32 computeGroupSizeNoTag(const id value);
249 |
250 | /**
251 | * Compute the number of bytes that would be needed to encode a
252 | * {@code group} field represented by an {@code PBUnknownFieldSet}, including
253 | * tag.
254 | */
255 | SInt32 computeUnknownGroupSizeNoTag(const PBUnknownFieldSet* value);
256 |
257 | /**
258 | * Compute the number of bytes that would be needed to encode an
259 | * embedded message field, including tag.
260 | */
261 | SInt32 computeMessageSizeNoTag(const id value);
262 |
263 | /**
264 | * Compute the number of bytes that would be needed to encode a
265 | * {@code bytes} field, including tag.
266 | */
267 | SInt32 computeDataSizeNoTag(const NSData* value);
268 |
269 | /**
270 | * Compute the number of bytes that would be needed to encode a
271 | * {@code uint32} field, including tag.
272 | */
273 | SInt32 computeUInt32SizeNoTag(SInt32 value);
274 |
275 | /**
276 | * Compute the number of bytes that would be needed to encode an
277 | * enum field, including tag. Caller is responsible for converting the
278 | * enum value to its numeric value.
279 | */
280 | SInt32 computeEnumSizeNoTag(SInt32 value);
281 |
282 | /**
283 | * Compute the number of bytes that would be needed to encode an
284 | * {@code sfixed32} field, including tag.
285 | */
286 | SInt32 computeSFixed32SizeNoTag(SInt32 value);
287 |
288 | /**
289 | * Compute the number of bytes that would be needed to encode an
290 | * {@code sfixed64} field, including tag.
291 | */
292 | SInt32 computeSFixed64SizeNoTag(SInt64 value);
293 |
294 | /**
295 | * Compute the number of bytes that would be needed to encode an
296 | * {@code sint32} field, including tag.
297 | */
298 | SInt32 computeSInt32SizeNoTag(SInt32 value);
299 |
300 | /**
301 | * Compute the number of bytes that would be needed to encode an
302 | * {@code sint64} field, including tag.
303 | */
304 | SInt32 computeSInt64SizeNoTag(SInt64 value);
305 |
306 | /**
307 | * Compute the number of bytes that would be needed to encode a varint.
308 | * {@code value} is treated as unsigned, so it won't be sign-extended if
309 | * negative.
310 | */
311 | SInt32 computeRawVarint32Size(SInt32 value);
312 |
313 | /** Compute the number of bytes that would be needed to encode a varint. */
314 | SInt32 computeRawVarint64Size(SInt64 value);
315 |
316 | /**
317 | * Compute the number of bytes that would be needed to encode a
318 | * MessageSet extension to the stream. For historical reasons,
319 | * the wire format differs from normal fields.
320 | */
321 | SInt32 computeMessageSetExtensionSize(SInt32 fieldNumber, const id value);
322 |
323 | /**
324 | * Compute the number of bytes that would be needed to encode an
325 | * unparsed MessageSet extension field to the stream. For
326 | * historical reasons, the wire format differs from normal fields.
327 | */
328 | SInt32 computeRawMessageSetExtensionSize(SInt32 fieldNumber, const NSData* value);
329 |
330 | /**
331 | * Compute the number of bytes that would be needed to encode an
332 | * enum field, including tag. Caller is responsible for converting the
333 | * enum value to its numeric value.
334 | */
335 | SInt32 computeEnumSize(SInt32 fieldNumber, SInt32 value);
336 |
--------------------------------------------------------------------------------
/GCDAsyncSocket/ProtobufBuffer/Utilities.m:
--------------------------------------------------------------------------------
1 | // Protocol Buffers for Objective C
2 | //
3 | // Copyright 2010 Booyah Inc.
4 | // Copyright 2008 Cyrus Najmabadi
5 | //
6 | // Licensed under the Apache License, Version 2.0 (the "License");
7 | // you may not use this file except in compliance with the License.
8 | // You may obtain a copy of the License at
9 | //
10 | // http://www.apache.org/licenses/LICENSE-2.0
11 | //
12 | // Unless required by applicable law or agreed to in writing, software
13 | // distributed under the License is distributed on an "AS IS" BASIS,
14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | // See the License for the specific language governing permissions and
16 | // limitations under the License.
17 |
18 | #import "Utilities.h"
19 |
20 | #import "UnknownFieldSet.h"
21 | #import "WireFormat.h"
22 |
23 | const SInt32 LITTLE_ENDIAN_32_SIZE = 4;
24 | const SInt32 LITTLE_ENDIAN_64_SIZE = 8;
25 |
26 |
27 | SInt64 convertFloat64ToInt64(Float64 v) {
28 | union { Float64 f; SInt64 i; } u;
29 | u.f = v;
30 | return u.i;
31 | }
32 |
33 |
34 | SInt32 convertFloat32ToInt32(Float32 v) {
35 | union { Float32 f; SInt32 i; } u;
36 | u.f = v;
37 | return u.i;
38 | }
39 |
40 |
41 | Float64 convertInt64ToFloat64(SInt64 v) {
42 | union { Float64 f; SInt64 i; } u;
43 | u.i = v;
44 | return u.f;
45 | }
46 |
47 |
48 | Float32 convertInt32ToFloat32(SInt32 v) {
49 | union { Float32 f; SInt32 i; } u;
50 | u.i = v;
51 | return u.f;
52 | }
53 |
54 |
55 | UInt64 convertInt64ToUInt64(SInt64 v) {
56 | union { SInt64 i; UInt64 u; } u;
57 | u.i = v;
58 | return u.u;
59 | }
60 |
61 |
62 | SInt64 convertUInt64ToInt64(UInt64 v) {
63 | union { SInt64 i; UInt64 u; } u;
64 | u.u = v;
65 | return u.i;
66 | }
67 |
68 | UInt32 convertInt32ToUInt32(SInt32 v) {
69 | union { SInt32 i; UInt32 u; } u;
70 | u.i = v;
71 | return u.u;
72 | }
73 |
74 |
75 | SInt32 convertUInt32ToInt32(UInt32 v) {
76 | union { SInt32 i; UInt32 u; } u;
77 | u.u = v;
78 | return u.i;
79 | }
80 |
81 |
82 | SInt32 logicalRightShift32(SInt32 value, SInt32 spaces) {
83 | return convertUInt32ToInt32((convertInt32ToUInt32(value) >> spaces));
84 | }
85 |
86 |
87 | SInt64 logicalRightShift64(SInt64 value, SInt32 spaces) {
88 | return convertUInt64ToInt64((convertInt64ToUInt64(value) >> spaces));
89 | }
90 |
91 |
92 | SInt32 decodeZigZag32(SInt32 n) {
93 | return logicalRightShift32(n, 1) ^ -(n & 1);
94 | }
95 |
96 |
97 | SInt64 decodeZigZag64(SInt64 n) {
98 | return logicalRightShift64(n, 1) ^ -(n & 1);
99 | }
100 |
101 |
102 | SInt32 encodeZigZag32(SInt32 n) {
103 | // Note: the right-shift must be arithmetic
104 | return (n << 1) ^ (n >> 31);
105 | }
106 |
107 |
108 | SInt64 encodeZigZag64(SInt64 n) {
109 | // Note: the right-shift must be arithmetic
110 | return (n << 1) ^ (n >> 63);
111 | }
112 |
113 |
114 | SInt32 computeDoubleSizeNoTag(Float64 value) {
115 | return LITTLE_ENDIAN_64_SIZE;
116 | }
117 |
118 |
119 | SInt32 computeFloatSizeNoTag(Float32 value) {
120 | return LITTLE_ENDIAN_32_SIZE;
121 | }
122 |
123 |
124 | SInt32 computeUInt64SizeNoTag(SInt64 value) {
125 | return computeRawVarint64Size(value);
126 | }
127 |
128 |
129 | SInt32 computeInt64SizeNoTag(SInt64 value) {
130 | return computeRawVarint64Size(value);
131 | }
132 |
133 |
134 | SInt32 computeInt32SizeNoTag(SInt32 value) {
135 | if (value >= 0) {
136 | return computeRawVarint32Size(value);
137 | } else {
138 | // Must sign-extend.
139 | return 10;
140 | }
141 | }
142 |
143 |
144 | SInt32 computeFixed64SizeNoTag(SInt64 value) {
145 | return LITTLE_ENDIAN_64_SIZE;
146 | }
147 |
148 |
149 | SInt32 computeFixed32SizeNoTag(SInt32 value) {
150 | return LITTLE_ENDIAN_32_SIZE;
151 | }
152 |
153 |
154 | SInt32 computeBoolSizeNoTag(BOOL value) {
155 | return 1;
156 | }
157 |
158 |
159 | SInt32 computeStringSizeNoTag(const NSString* value) {
160 | const UInt32 length = (UInt32)[value lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
161 | return computeRawVarint32Size(length) + length;
162 | }
163 |
164 |
165 | SInt32 computeGroupSizeNoTag(const id value) {
166 | return [value serializedSize];
167 | }
168 |
169 |
170 | SInt32 computeUnknownGroupSizeNoTag(const PBUnknownFieldSet* value) {
171 | return value.serializedSize;
172 | }
173 |
174 |
175 | SInt32 computeMessageSizeNoTag(const id value) {
176 | SInt32 size = [value serializedSize];
177 | return computeRawVarint32Size(size) + size;
178 | }
179 |
180 |
181 | SInt32 computeDataSizeNoTag(const NSData* value) {
182 | return computeRawVarint32Size((UInt32)value.length) + (UInt32)value.length;
183 | }
184 |
185 |
186 | SInt32 computeUInt32SizeNoTag(SInt32 value) {
187 | return computeRawVarint32Size(value);
188 | }
189 |
190 |
191 | SInt32 computeEnumSizeNoTag(SInt32 value) {
192 | return computeRawVarint32Size(value);
193 | }
194 |
195 |
196 | SInt32 computeSFixed32SizeNoTag(SInt32 value) {
197 | return LITTLE_ENDIAN_32_SIZE;
198 | }
199 |
200 |
201 | SInt32 computeSFixed64SizeNoTag(SInt64 value) {
202 | return LITTLE_ENDIAN_64_SIZE;
203 | }
204 |
205 |
206 | SInt32 computeSInt32SizeNoTag(SInt32 value) {
207 | return computeRawVarint32Size(encodeZigZag32(value));
208 | }
209 |
210 |
211 | SInt32 computeSInt64SizeNoTag(SInt64 value) {
212 | return computeRawVarint64Size(encodeZigZag64(value));
213 | }
214 |
215 |
216 | SInt32 computeDoubleSize(SInt32 fieldNumber, Float64 value) {
217 | return computeTagSize(fieldNumber) + computeDoubleSizeNoTag(value);
218 | }
219 |
220 |
221 | SInt32 computeFloatSize(SInt32 fieldNumber, Float32 value) {
222 | return computeTagSize(fieldNumber) + computeFloatSizeNoTag(value);
223 | }
224 |
225 |
226 | SInt32 computeUInt64Size(SInt32 fieldNumber, SInt64 value) {
227 | return computeTagSize(fieldNumber) + computeUInt64SizeNoTag(value);
228 | }
229 |
230 |
231 | SInt32 computeInt64Size(SInt32 fieldNumber, SInt64 value) {
232 | return computeTagSize(fieldNumber) + computeInt64SizeNoTag(value);
233 | }
234 |
235 |
236 | SInt32 computeInt32Size(SInt32 fieldNumber, SInt32 value) {
237 | return computeTagSize(fieldNumber) + computeInt32SizeNoTag(value);
238 | }
239 |
240 |
241 | SInt32 computeFixed64Size(SInt32 fieldNumber, SInt64 value) {
242 | return computeTagSize(fieldNumber) + computeFixed64SizeNoTag(value);
243 | }
244 |
245 |
246 | SInt32 computeFixed32Size(SInt32 fieldNumber, SInt32 value) {
247 | return computeTagSize(fieldNumber) + computeFixed32SizeNoTag(value);
248 | }
249 |
250 |
251 | SInt32 computeBoolSize(SInt32 fieldNumber, BOOL value) {
252 | return computeTagSize(fieldNumber) + computeBoolSizeNoTag(value);
253 | }
254 |
255 |
256 | SInt32 computeStringSize(SInt32 fieldNumber, const NSString* value) {
257 | return computeTagSize(fieldNumber) + computeStringSizeNoTag(value);
258 | }
259 |
260 |
261 | SInt32 computeGroupSize(SInt32 fieldNumber, const id value) {
262 | return computeTagSize(fieldNumber) * 2 + computeGroupSizeNoTag(value);
263 | }
264 |
265 |
266 | SInt32 computeUnknownGroupSize(SInt32 fieldNumber, const PBUnknownFieldSet* value) {
267 | return computeTagSize(fieldNumber) * 2 + computeUnknownGroupSizeNoTag(value);
268 | }
269 |
270 |
271 | SInt32 computeMessageSize(SInt32 fieldNumber, const id value) {
272 | return computeTagSize(fieldNumber) + computeMessageSizeNoTag(value);
273 | }
274 |
275 |
276 | SInt32 computeDataSize(SInt32 fieldNumber, const NSData* value) {
277 | return computeTagSize(fieldNumber) + computeDataSizeNoTag(value);
278 | }
279 |
280 |
281 | SInt32 computeUInt32Size(SInt32 fieldNumber, SInt32 value) {
282 | return computeTagSize(fieldNumber) + computeUInt32SizeNoTag(value);
283 | }
284 |
285 |
286 | SInt32 computeEnumSize(SInt32 fieldNumber, SInt32 value) {
287 | return computeTagSize(fieldNumber) + computeEnumSizeNoTag(value);
288 | }
289 |
290 |
291 | SInt32 computeSFixed32Size(SInt32 fieldNumber, SInt32 value) {
292 | return computeTagSize(fieldNumber) + computeSFixed32SizeNoTag(value);
293 | }
294 |
295 |
296 | SInt32 computeSFixed64Size(SInt32 fieldNumber, SInt64 value) {
297 | return computeTagSize(fieldNumber) + computeSFixed64SizeNoTag(value);
298 | }
299 |
300 |
301 | SInt32 computeSInt32Size(SInt32 fieldNumber, SInt32 value) {
302 | return computeTagSize(fieldNumber) + computeSInt32SizeNoTag(value);
303 | }
304 |
305 |
306 | SInt32 computeTagSize(SInt32 fieldNumber) {
307 | return computeRawVarint32Size(PBWireFormatMakeTag(fieldNumber, 0));
308 | }
309 |
310 |
311 | SInt32 computeSInt64Size(SInt32 fieldNumber, SInt64 value) {
312 | return computeTagSize(fieldNumber) +
313 | computeRawVarint64Size(encodeZigZag64(value));
314 | }
315 |
316 |
317 | SInt32 computeRawVarint32Size(SInt32 value) {
318 | if ((value & (0xffffffff << 7)) == 0) return 1;
319 | if ((value & (0xffffffff << 14)) == 0) return 2;
320 | if ((value & (0xffffffff << 21)) == 0) return 3;
321 | if ((value & (0xffffffff << 28)) == 0) return 4;
322 | return 5;
323 | }
324 |
325 |
326 | SInt32 computeRawVarint64Size(SInt64 value) {
327 | if ((value & (0xffffffffffffffffL << 7)) == 0) return 1;
328 | if ((value & (0xffffffffffffffffL << 14)) == 0) return 2;
329 | if ((value & (0xffffffffffffffffL << 21)) == 0) return 3;
330 | if ((value & (0xffffffffffffffffL << 28)) == 0) return 4;
331 | if ((value & (0xffffffffffffffffL << 35)) == 0) return 5;
332 | if ((value & (0xffffffffffffffffL << 42)) == 0) return 6;
333 | if ((value & (0xffffffffffffffffL << 49)) == 0) return 7;
334 | if ((value & (0xffffffffffffffffL << 56)) == 0) return 8;
335 | if ((value & (0xffffffffffffffffL << 63)) == 0) return 9;
336 | return 10;
337 | }
338 |
339 |
340 | SInt32 computeMessageSetExtensionSize(SInt32 fieldNumber, const id value) {
341 | return computeTagSize(PBWireFormatMessageSetItem) * 2 +
342 | computeUInt32Size(PBWireFormatMessageSetTypeId, fieldNumber) +
343 | computeMessageSize(PBWireFormatMessageSetMessage, value);
344 | }
345 |
346 |
347 | SInt32 computeRawMessageSetExtensionSize(SInt32 fieldNumber, const NSData* value) {
348 | return computeTagSize(PBWireFormatMessageSetItem) * 2 +
349 | computeUInt32Size(PBWireFormatMessageSetTypeId, fieldNumber) +
350 | computeDataSize(PBWireFormatMessageSetMessage, value);
351 | }
352 |
--------------------------------------------------------------------------------
/GCDAsyncSocket/ProtobufBuffer/WireFormat.h:
--------------------------------------------------------------------------------
1 | // Protocol Buffers for Objective C
2 | //
3 | // Copyright 2010 Booyah Inc.
4 | // Copyright 2008 Cyrus Najmabadi
5 | //
6 | // Licensed under the Apache License, Version 2.0 (the "License");
7 | // you may not use this file except in compliance with the License.
8 | // You may obtain a copy of the License at
9 | //
10 | // http://www.apache.org/licenses/LICENSE-2.0
11 | //
12 | // Unless required by applicable law or agreed to in writing, software
13 | // distributed under the License is distributed on an "AS IS" BASIS,
14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | // See the License for the specific language governing permissions and
16 | // limitations under the License.
17 | #import
18 |
19 | typedef enum {
20 | PBWireFormatVarint = 0,
21 | PBWireFormatFixed64 = 1,
22 | PBWireFormatLengthDelimited = 2,
23 | PBWireFormatStartGroup = 3,
24 | PBWireFormatEndGroup = 4,
25 | PBWireFormatFixed32 = 5,
26 |
27 | PBWireFormatTagTypeBits = 3,
28 | PBWireFormatTagTypeMask = 7 /* = (1 << PBWireFormatTagTypeBits) - 1*/,
29 |
30 | PBWireFormatMessageSetItem = 1,
31 | PBWireFormatMessageSetTypeId = 2,
32 | PBWireFormatMessageSetMessage = 3
33 | } PBWireFormat;
34 |
35 | SInt32 PBWireFormatMakeTag(SInt32 fieldNumber, SInt32 wireType);
36 | SInt32 PBWireFormatGetTagWireType(SInt32 tag);
37 | SInt32 PBWireFormatGetTagFieldNumber(SInt32 tag);
38 |
39 | #define PBWireFormatMessageSetItemTag (PBWireFormatMakeTag(PBWireFormatMessageSetItem, PBWireFormatStartGroup))
40 | #define PBWireFormatMessageSetItemEndTag (PBWireFormatMakeTag(PBWireFormatMessageSetItem, PBWireFormatEndGroup))
41 | #define PBWireFormatMessageSetTypeIdTag (PBWireFormatMakeTag(PBWireFormatMessageSetTypeId, PBWireFormatVarint))
42 | #define PBWireFormatMessageSetMessageTag (PBWireFormatMakeTag(PBWireFormatMessageSetMessage, PBWireFormatLengthDelimited))
43 |
--------------------------------------------------------------------------------
/GCDAsyncSocket/ProtobufBuffer/WireFormat.m:
--------------------------------------------------------------------------------
1 | // Protocol Buffers for Objective C
2 | //
3 | // Copyright 2010 Booyah Inc.
4 | // Copyright 2008 Cyrus Najmabadi
5 | //
6 | // Licensed under the Apache License, Version 2.0 (the "License");
7 | // you may not use this file except in compliance with the License.
8 | // You may obtain a copy of the License at
9 | //
10 | // http://www.apache.org/licenses/LICENSE-2.0
11 | //
12 | // Unless required by applicable law or agreed to in writing, software
13 | // distributed under the License is distributed on an "AS IS" BASIS,
14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | // See the License for the specific language governing permissions and
16 | // limitations under the License.
17 |
18 | #import "WireFormat.h"
19 |
20 | #import "Utilities.h"
21 |
22 | SInt32 PBWireFormatMakeTag(SInt32 fieldNumber, SInt32 wireType) {
23 | return (fieldNumber << PBWireFormatTagTypeBits) | wireType;
24 | }
25 |
26 |
27 | SInt32 PBWireFormatGetTagWireType(SInt32 tag) {
28 | return tag & PBWireFormatTagTypeMask;
29 | }
30 |
31 |
32 | SInt32 PBWireFormatGetTagFieldNumber(SInt32 tag) {
33 | return logicalRightShift32(tag, PBWireFormatTagTypeBits);
34 | }
35 |
--------------------------------------------------------------------------------
/GCDAsyncSocket/ServerURLModel.h:
--------------------------------------------------------------------------------
1 | //
2 | // ServerURLModel.h
3 | // GCDAsyncSocket
4 | //
5 | // Created by caokun on 16/7/8.
6 | // Copyright © 2016年 caokun. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | // 服务器地址类
12 | @interface ServerURLModel : NSObject
13 |
14 | @property (strong, nonatomic) NSString *hostName;
15 | @property (strong, nonatomic) NSString *ip;
16 | @property (strong, nonatomic) NSString *port;
17 |
18 | @property (assign, nonatomic) UInt32 loadFactor; // 负载因子
19 | @property (assign, nonatomic) UInt32 connectCount; // 连接数
20 | @property (assign, nonatomic) UInt32 delay; // 延迟
21 |
22 | - (instancetype)init;
23 | - (instancetype)initWithDictionary:(NSDictionary *)dic;
24 |
25 | @end
26 |
--------------------------------------------------------------------------------
/GCDAsyncSocket/ServerURLModel.m:
--------------------------------------------------------------------------------
1 | //
2 | // ServerURLModel.m
3 | // GCDAsyncSocket
4 | //
5 | // Created by caokun on 16/7/8.
6 | // Copyright © 2016年 caokun. All rights reserved.
7 | //
8 |
9 | #import "ServerURLModel.h"
10 |
11 | @implementation ServerURLModel
12 |
13 | - (instancetype)init {
14 | if (self = [super init]) {
15 | self.hostName = nil;
16 | self.ip = nil;
17 | self.port = nil;
18 | self.loadFactor = 10000000;
19 | self.delay = 10000000;
20 | self.connectCount = 10000000;
21 | }
22 | return self;
23 | }
24 |
25 | - (instancetype)initWithDictionary:(NSDictionary *)dic {
26 | if (self = [super init]) {
27 | if (dic) {
28 | self.hostName = dic[@"hostName"];
29 | self.ip = dic[@"ip"];
30 | self.port = dic[@"port"];
31 | self.loadFactor = 10000000;
32 | self.delay = 10000000;
33 | self.connectCount = 10000000;
34 | }
35 | }
36 | return self;
37 | }
38 |
39 | // encode 到 aCoder 中
40 | - (void)encodeWithCoder:(NSCoder *)aCoder {
41 | [aCoder encodeObject:self.hostName forKey:@"hostName"];
42 | [aCoder encodeObject:self.ip forKey:@"ip"];
43 | [aCoder encodeObject:self.port forKey:@"port"];
44 | }
45 |
46 | // 从 aDecoder 还原到类中
47 | - (id)initWithCoder:(NSCoder *)aDecoder {
48 | if (self = [super init]) {
49 | self.hostName = [aDecoder decodeObjectForKey:@"hostName"];
50 | self.ip = [aDecoder decodeObjectForKey:@"ip"];
51 | self.port = [aDecoder decodeObjectForKey:@"port"];
52 | }
53 | return self;
54 | }
55 |
56 | @end
57 |
--------------------------------------------------------------------------------
/GCDAsyncSocket/SocketManager.h:
--------------------------------------------------------------------------------
1 | //
2 | // SocketManager.h
3 | // GCDAsyncSocket使用
4 | //
5 | // Created by caokun on 16/7/1.
6 | // Copyright © 2016年 caokun. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "GCDAsyncSocket.h"
11 |
12 | @protocol SocketManagerDelegate
13 |
14 | - (void)socket:(GCDAsyncSocket *)socket didReadData:(NSData *)data;
15 | - (void)socket:(GCDAsyncSocket *)socket didConnect:(NSString *)host port:(uint16_t)port;
16 | - (void)socketDidDisconnect:(GCDAsyncSocket *)socket;
17 |
18 | @end
19 |
20 | // socket 连接管理类
21 | @interface SocketManager : NSObject
22 |
23 | @property (assign, nonatomic) BOOL isAutomatic; // 默认使用负载均衡
24 | @property (weak, nonatomic) id delegate;
25 |
26 | + (SocketManager *)instance; // 可以使用单例,也可以 alloc 一个新的临时用
27 |
28 | - (void)connectAutomatic:(void (^)())completion; // 负载均衡寻找服务器
29 | - (void)connectWithIp:(NSString *)ip port:(UInt16)port; // 手动连接服务器
30 | - (void)disConnect;
31 | - (void)send:(NSData *)data;
32 | - (BOOL)status;
33 |
34 | @end
35 |
36 |
--------------------------------------------------------------------------------
/GCDAsyncSocket/SocketManager.m:
--------------------------------------------------------------------------------
1 | //
2 | // SocketManager.m
3 | // GCDAsyncSocket使用
4 | //
5 | // Created by caokun on 16/7/1.
6 | // Copyright © 2016年 caokun. All rights reserved.
7 | //
8 |
9 | #import "SocketManager.h"
10 | #import "SpeedDectectManager.h"
11 |
12 | typedef void (^completionBlock)();
13 |
14 | @interface SocketManager ()
15 |
16 | @property (strong, nonatomic) GCDAsyncSocket *socket;
17 | @property (strong, nonatomic) dispatch_queue_t socketQueue; // 发数据的串行队列
18 | @property (strong, nonatomic) dispatch_queue_t receiveQueue; // 收数据处理的串行队列
19 | @property (strong, nonatomic) NSString *ip;
20 | @property (assign, nonatomic) UInt16 port;
21 | @property (assign, nonatomic) BOOL isConnecting;
22 | @property (strong, nonatomic) completionBlock completion; // 负载均衡结果回调
23 |
24 | @end
25 |
26 | @implementation SocketManager
27 |
28 | static SocketManager *instance = nil;
29 | static NSTimeInterval TimeOut = -1; // 超时时间, 超时会关闭 socket
30 |
31 | + (SocketManager *)instance {
32 | static dispatch_once_t onceToken;
33 | dispatch_once(&onceToken, ^{
34 | instance = [[SocketManager alloc] init];
35 | });
36 | return instance;
37 | }
38 |
39 | - (instancetype)init {
40 | if (self = [super init]) {
41 | self.isAutomatic = true;
42 | self.isConnecting = false;
43 | [self resetSocket];
44 | }
45 | return self;
46 | }
47 |
48 | - (dispatch_queue_t)socketQueue {
49 | if (_socketQueue == nil) {
50 | _socketQueue = dispatch_queue_create("com.sendSocket", DISPATCH_QUEUE_SERIAL);
51 | }
52 | return _socketQueue;
53 | }
54 |
55 | - (dispatch_queue_t)receiveQueue {
56 | if (_receiveQueue == nil) {
57 | _receiveQueue = dispatch_queue_create("com.receiveSocket", DISPATCH_QUEUE_SERIAL);
58 | }
59 | return _receiveQueue;
60 | }
61 |
62 | - (void)resetSocket {
63 | [self disConnect];
64 |
65 | self.socket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:self.socketQueue];
66 | self.socket.IPv6Enabled = true;
67 | self.socket.IPv4Enabled = true;
68 | self.socket.IPv4PreferredOverIPv6 = false; // 4 优先
69 | }
70 |
71 | // 负载均衡寻找服务器
72 | - (void)connectAutomatic:(void (^)())completion {
73 | __weak typeof(self) ws = self;
74 | dispatch_async(self.socketQueue, ^{
75 | ws.isAutomatic = true;
76 | [[SpeedDectectManager instance] startDectect:^(ServerURLModel *response, NSString *error) {
77 | ws.completion = completion;
78 | dispatch_async(self.socketQueue, ^{
79 | if (response != nil) {
80 | NSLog(@"找到最快的服务器");
81 | ws.isConnecting = true;
82 | ws.ip = response.ip;
83 | ws.port = (UInt16)[response.port intValue];
84 | [ws connectWithIp:response.ip port:(UInt16)[response.port intValue]];
85 | }
86 | });
87 | }];
88 | });
89 | }
90 |
91 | - (void)connectWithIp:(NSString *)ip port:(UInt16)port {
92 | self.ip = ip;
93 | self.port = port;
94 |
95 | [self resetSocket];
96 | NSError *error = nil;
97 | [self.socket connectToHost:self.ip onPort:self.port withTimeout:10 error:&error]; // 填写 地址,端口进行连接
98 | if (error != nil) {
99 | NSLog(@"连接错误:%@", error);
100 | }
101 | }
102 |
103 | - (void)disConnect {
104 | [self.socket disconnect];
105 | self.socket = nil;
106 | self.socketQueue = nil;
107 | }
108 |
109 | - (void)send:(NSData *)data {
110 | NSLog(@"socket send 发送数据");
111 | // socket 的操作要在 self.socketQueue(socket 的代理队列)中才有效,不允许其他线程来设置本 socket
112 | dispatch_async(self.socketQueue, ^{
113 | if (self.socket == nil || self.socket.isDisconnected) {
114 | if (self.isAutomatic) { // 自动重连 + 启用负载均衡
115 | NSLog(@"启用负载均衡");
116 | __weak typeof(self) ws = self;
117 | [self connectAutomatic:^{
118 | NSLog(@"启用了负载均衡");
119 | if (ws.socket != nil && ws.socket.isConnected) {
120 | NSLog(@"发送了数据");
121 | [ws.socket readDataWithTimeout:TimeOut tag:100];
122 | [ws.socket writeData:data withTimeout:TimeOut tag:100];
123 | } else {
124 | NSLog(@"未发送数据");
125 | }
126 | }];
127 | return ;
128 |
129 | } else {
130 | NSLog(@"不启用负载均衡");
131 | [self connectWithIp:self.ip port:self.port]; // 不启用负载
132 | }
133 | }
134 | [self.socket readDataWithTimeout:TimeOut tag:100]; // 每次都要设置接收数据的时间, tag
135 | [self.socket writeData:data withTimeout:TimeOut tag:100]; // 再发送
136 | });
137 | }
138 |
139 | - (BOOL)status {
140 | if (self.socket != nil && self.socket.isConnected) {
141 | return true;
142 | }
143 | return false;
144 | }
145 |
146 | // 代理方法
147 | - (void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port {
148 | NSLog(@"连接成功:%@, %d", host, port);
149 | dispatch_async(self.receiveQueue, ^{
150 | if (self.delegate && [self.delegate respondsToSelector:@selector(socket:didConnect:port:)]) {
151 | [self.delegate socket:sock didConnect:host port:port];
152 | }
153 | if (_isConnecting == true) {
154 | _isConnecting = false;
155 | if (self.completion) {
156 | self.completion();
157 | self.completion = nil;
158 | }
159 | }
160 | });
161 | }
162 |
163 | - (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err {
164 | NSLog(@"断开连接socketDidDisconnect");
165 | dispatch_async(self.receiveQueue, ^{
166 | if (self.delegate && [self.delegate respondsToSelector:@selector(socketDidDisconnect:)]) {
167 | [self.delegate socketDidDisconnect:sock];
168 | }
169 | self.socket = nil;
170 | self.socketQueue = nil;
171 | });
172 | }
173 |
174 | - (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag {
175 | dispatch_async(self.receiveQueue, ^{
176 | // 防止 didReadData 被阻塞,用个其他队列里的线程去回调 block
177 | if (self.delegate && [self.delegate respondsToSelector:@selector(socket:didReadData:)]) {
178 | [self.delegate socket:sock didReadData:data];
179 | }
180 | });
181 | [self.socket readDataWithTimeout:TimeOut tag:100]; // 设置下次接收数据的时间, tag
182 | }
183 |
184 | @end
185 |
186 |
--------------------------------------------------------------------------------
/GCDAsyncSocket/SpeedDectectManager.h:
--------------------------------------------------------------------------------
1 | //
2 | // SpeedDectectManager.h
3 | // GCDAsyncSocket
4 | //
5 | // Created by caokun on 16/7/8.
6 | // Copyright © 2016年 caokun. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "ServerURLModel.h"
11 |
12 | typedef void (^serverURL)(ServerURLModel *response, NSString *error);
13 | typedef void (^serverURLs)(NSArray *response, NSString *error);
14 |
15 | // 测速服务类,客户端负载均衡
16 | @interface SpeedDectectManager : NSObject
17 |
18 | + (SpeedDectectManager *)instance;
19 |
20 | - (void)startDectect:(serverURL)complete; // 寻找最快的服务器,默认缓存 300 秒
21 | - (void)requestServiceListsWithCache:(serverURLs)complete; // 获取服务器列表,默认缓存1天
22 |
23 | @end
24 |
25 |
--------------------------------------------------------------------------------
/GCDAsyncSocket/SpeedDectectManager.m:
--------------------------------------------------------------------------------
1 | //
2 | // SpeedDectectManager.m
3 | // GCDAsyncSocket
4 | //
5 | // Created by caokun on 16/7/8.
6 | // Copyright © 2016年 caokun. All rights reserved.
7 | //
8 |
9 | #import "SpeedDectectManager.h"
10 | #import "AFNetworking/AFNetworking.h"
11 | #import "Common.pb.h"
12 | #import "GCDAsyncSocket.h"
13 |
14 | #define ServiceListsCacheKey @"ServiceListsCacheKey" // 服务器列表缓存 key
15 | #define ServiceListsStampKey @"ServiceListsStampKey" // 时间戳
16 | #define FasterServiceCacheKey @"FasterServiceCacheKey" // 最快的服务器地址 key
17 | #define FasterServiceStampKey @"FasterServiceStampKey" // 时间戳
18 |
19 | @interface SpeedDectectManager ()
20 |
21 | @property (strong, nonatomic) NSMutableArray *socketArray;
22 | @property (strong, nonatomic) dispatch_queue_t socketQueue;
23 | @property (assign, nonatomic) UInt32 seq;
24 | @property (strong, nonatomic) NSArray *serverModels;
25 | @property (assign, nonatomic) NSInteger receiveCount; // 返回的测速包个数
26 | @property (strong, nonatomic) serverURL completion; // 回调 block
27 | @property (strong, nonatomic) NSTimer *timer; // 超时定时器
28 |
29 | @end
30 |
31 | @implementation SpeedDectectManager
32 |
33 | static SpeedDectectManager *instance = nil;
34 |
35 | + (SpeedDectectManager *)instance {
36 | static dispatch_once_t onceToken;
37 | dispatch_once(&onceToken, ^{
38 | instance = [[SpeedDectectManager alloc] init];
39 | });
40 | return instance;
41 | }
42 |
43 | - (instancetype)init {
44 | if (self = [super init]) {
45 | self.seq = 1000;
46 | }
47 | return self;
48 | }
49 |
50 | - (dispatch_queue_t)socketQueue {
51 | if (_socketQueue == nil) {
52 | _socketQueue = dispatch_queue_create("com.speedSocket", DISPATCH_QUEUE_CONCURRENT);
53 | }
54 | return _socketQueue;
55 | }
56 |
57 | - (UInt32)seq {
58 | _seq = _seq + 1;
59 | return _seq;
60 | }
61 |
62 | - (NSMutableArray *)socketArray {
63 | if (_socketArray == nil) {
64 | _socketArray = [[NSMutableArray alloc] init];
65 | }
66 | return _socketArray;
67 | }
68 |
69 | // 开始测试服务器连接速度
70 | - (void)startDectect:(serverURL)complete {
71 | NSData *obj = [[NSUserDefaults standardUserDefaults] objectForKey:FasterServiceCacheKey];
72 | NSDate *date = [[NSUserDefaults standardUserDefaults] objectForKey:FasterServiceStampKey];
73 | NSDate *curDate = [NSDate dateWithTimeIntervalSinceNow:0];
74 | NSTimeInterval seconds = 10000; // 相差的秒数
75 |
76 | if (date != nil && curDate != nil) {
77 | seconds = ABS([date timeIntervalSinceDate:curDate]);
78 | }
79 | // 判断是否在 300 秒内, 使用缓存
80 | if (obj != nil || date != nil || seconds < 300) {
81 | ServerURLModel *m = [NSKeyedUnarchiver unarchiveObjectWithData:obj];
82 | complete(m, nil);
83 | return ;
84 | }
85 |
86 | // 超时不使用缓存
87 | __weak typeof(self) ws = self;
88 | self.receiveCount = 0;
89 | self.completion = complete;
90 |
91 | // 获取服务器列表有缓存
92 | [ws requestServiceListsWithCache:^(NSArray *response, NSString *error) {
93 | ws.serverModels = response;
94 | // 测试连接,由于后台漏掉 seq 字段,此处用 SocketManager 来区分返回的包,创建多个线程,每个线程一个 socket 异步请求
95 | for (ServerURLModel *m in response) {
96 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
97 | // 该段代码在不同的线程
98 | GCDAsyncSocket *socket = [[GCDAsyncSocket alloc] initWithDelegate:ws delegateQueue:ws.socketQueue];
99 | socket.IPv6Enabled = true;
100 | socket.IPv4Enabled = true;
101 | socket.IPv4PreferredOverIPv6 = false;
102 |
103 | NSError *error = nil;
104 | [socket connectToHost:m.ip onPort:(UInt16)[m.port intValue] withTimeout:10 error:&error];
105 | if (error == nil) {
106 | [socket readDataWithTimeout:10 tag:100];
107 | [socket writeData:[ws speedTest] withTimeout:10 tag:100]; // 发送测速包
108 | }
109 | [ws.socketArray addObject:socket]; // 保证 socket 不 ARC 释放,导致断开
110 | });
111 | }
112 | // 测速包 4 秒超时
113 | [self closeTimer];
114 | __weak typeof(self) ws = self;
115 | dispatch_async(dispatch_get_main_queue(), ^{
116 | ws.timer = [NSTimer scheduledTimerWithTimeInterval:4 target:ws selector:@selector(timeOut:) userInfo:nil repeats:false];
117 | });
118 | }];
119 | }
120 |
121 | // 生成测速包
122 | - (NSData *)speedTest {
123 | load_dector_msgBuilder *msg = [load_dector_msg builder];
124 | [msg setReq:true];
125 | [msg setSendTime:CACurrentMediaTime() * 1000]; // 时间戳
126 |
127 | rpc_msg_rootBuilder *rootMsg = [rpc_msg_root builder];
128 | [rootMsg setService:eum_rpc_serviceCommonService];
129 | [rootMsg setMethod:eum_method_typeLoadDetector];
130 | [rootMsg setBody:[[msg build] data]];
131 | UInt32 s = self.seq;
132 | [rootMsg setSeq:s];
133 |
134 | rpc_msg_root *root = [rootMsg build];
135 | SInt32 length = [root serializedSize]; // 包头是 32 位的整型,表示包体长度
136 | NSMutableData *data = [NSMutableData dataWithBytes:&length length:4];
137 | [data appendData:[root data]]; // 追加包体
138 |
139 | return data;
140 | }
141 |
142 | // socket 接收数据
143 | - (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag {
144 | // 此处有个风险,需保证测速包是一次性返回的,由于测速包是 17 个字节比较小,可以一次返回
145 | if (data.length >= 4) {
146 | NSData *rootData = [data subdataWithRange:NSMakeRange(4, data.length - 4)];
147 | rpc_msg_root *root = [rpc_msg_root parseFromData:rootData];
148 | load_dector_msg *speed = [load_dector_msg parseFromData:root.body];
149 |
150 | for (ServerURLModel *m in self.serverModels) {
151 | if ([m.ip isEqualToString:sock.connectedHost] && (uint16_t)[m.port intValue] == sock.connectedPort) {
152 | m.loadFactor = speed.loadFactor;
153 | m.connectCount = speed.connectCount;
154 | m.delay = CACurrentMediaTime() * 1000 - speed.sendTime;
155 | self.receiveCount += 1;
156 | break;
157 | }
158 | }
159 | // 测速包全部返回,计算最快服务器
160 | if (self.receiveCount == self.serverModels.count) {
161 | [self calculate:self.serverModels];
162 | [self closeTimer];
163 | [self.socketArray removeAllObjects]; // 清空 socket 连接
164 | return ;
165 | }
166 | }
167 | }
168 |
169 | - (void)closeTimer {
170 | __weak typeof(self) ws = self;
171 | dispatch_async(dispatch_get_main_queue(), ^{
172 | if (ws.timer) {
173 | [ws.timer invalidate];
174 | ws.timer = nil;
175 | }
176 | });
177 | }
178 |
179 | - (void)timeOut:(NSTimer *)timer {
180 | [self calculate:self.serverModels];
181 | [self closeTimer];
182 | [self.socketArray removeAllObjects]; // 清空 socket 连接
183 | }
184 |
185 | // 负载因子不超过平均数的10%,且延迟最小的服务器
186 | - (void)calculate:(NSArray *)array {
187 | // 按延迟排序
188 | NSArray *sorted = [array sortedArrayUsingComparator:^NSComparisonResult(id _Nonnull obj1, id _Nonnull obj2) {
189 | ServerURLModel *m1 = obj1;
190 | ServerURLModel *m2 = obj2;
191 |
192 | if (m1.delay > m2.delay) {
193 | return NSOrderedDescending;
194 | } else {
195 | return NSOrderedAscending;
196 | }
197 | }];
198 | // 去掉超时的包
199 | NSMutableArray *valuableArray = [[NSMutableArray alloc] init];
200 | for (ServerURLModel *m in sorted) {
201 | if (m.loadFactor < 10000000) { // 超过 10000000 是超时的
202 | [valuableArray addObject:m];
203 | }
204 | }
205 | if (valuableArray.count == 0) {
206 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
207 | self.completion(nil, @"no servers");
208 | });
209 | return ;
210 | }
211 | // 计算平均数, 找出不超过平均数 10% 的返回
212 | CGFloat sum = 0;
213 | CGFloat ave = 0;
214 | for (ServerURLModel *m in valuableArray) {
215 | sum += m.loadFactor;
216 | }
217 | ave = sum / valuableArray.count * 1.1;
218 | for (ServerURLModel *m in valuableArray) {
219 | if (m.loadFactor < ave) {
220 | // 本地缓存
221 | NSData *data = [NSKeyedArchiver archivedDataWithRootObject:m];
222 | [[NSUserDefaults standardUserDefaults] setObject:data forKey:FasterServiceCacheKey];
223 | [[NSUserDefaults standardUserDefaults] setObject:[NSDate dateWithTimeIntervalSinceNow:0] forKey:FasterServiceStampKey];
224 |
225 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
226 | NSLog(@"使用 %@", m.ip);
227 | self.completion(m, nil); // 返回最快的服务器
228 | });
229 | break;
230 | }
231 | }
232 | }
233 |
234 | // 获取服务器列表并缓存一天
235 | - (void)requestServiceListsWithCache:(serverURLs)complete {
236 | NSData *obj = [[NSUserDefaults standardUserDefaults] objectForKey:ServiceListsCacheKey];
237 | NSDate *date = [[NSUserDefaults standardUserDefaults] objectForKey:ServiceListsStampKey];
238 | NSDate *curDate = [NSDate dateWithTimeIntervalSinceNow:0];
239 | NSTimeInterval seconds = 24 * 3600; // 相差的秒数
240 |
241 | if (date != nil && curDate != nil) {
242 | seconds = ABS([date timeIntervalSinceDate:curDate]);
243 | }
244 | // 判断是否超过一天
245 | if (obj == nil || date == nil || seconds > 24 * 3600) {
246 | [self requestServiceLists:^(NSArray *response, NSString *error) {
247 | // 本地缓存 + 时间戳
248 | NSData *data = [NSKeyedArchiver archivedDataWithRootObject:response];
249 | [[NSUserDefaults standardUserDefaults] setObject:data forKey:ServiceListsCacheKey];
250 | [[NSUserDefaults standardUserDefaults] setObject:[NSDate dateWithTimeIntervalSinceNow:0] forKey:ServiceListsStampKey];
251 | complete(response, nil);
252 | }];
253 | } else { // 读取缓存
254 | NSArray *array = [NSKeyedUnarchiver unarchiveObjectWithData:obj];
255 | complete(array, nil);
256 | }
257 | }
258 |
259 | // 获取服务器列表
260 | // 用户名跟密码由于是公司的账号,还有一些公司内部的域名,不敢随便公布了
261 | - (void)requestServiceLists:(serverURLs)complete {
262 | // 默认服务器列表
263 | ServerURLModel *defaultModel = [[ServerURLModel alloc] init];
264 | defaultModel.ip = @"127.0.0.1";
265 | defaultModel.port = @"1234";
266 |
267 | // 发起请求
268 | AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc] initWithBaseURL:[[NSURL alloc] initWithString:@"https://www.baidu.com/"]];
269 | manager.responseSerializer = [AFHTTPResponseSerializer serializer];
270 | manager.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"text/html"];
271 |
272 | NSDictionary *params = @{@"userName":@"用户名", @"service":@"T", @"api":@"sf"};
273 |
274 | // get 请求
275 | [manager GET:@"" parameters:params progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
276 | // jsonString -> jsonData -> NSDictionary -> model
277 | NSString *jsonString = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
278 | NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
279 | NSError *error = nil;
280 | NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&error];
281 | if (error) {
282 | NSLog(@"json 解析失败");
283 | complete(@[defaultModel], nil);
284 | } else {
285 | NSArray *responses = dic[@"response"];
286 | NSMutableArray *array = [[NSMutableArray alloc] init];
287 | for (NSDictionary *d in responses) {
288 | ServerURLModel *m = [[ServerURLModel alloc] initWithDictionary:d];
289 | [array addObject:m];
290 | }
291 | complete(array, nil);
292 | }
293 | } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
294 | NSLog(@"获取服务器列表失败");
295 | complete(@[defaultModel], nil);
296 | }];
297 | }
298 |
299 | @end
300 |
301 |
--------------------------------------------------------------------------------
/GCDAsyncSocket/TCPAPI.h:
--------------------------------------------------------------------------------
1 | //
2 | // TCPAPI.h
3 | // GCDAsyncSocket使用
4 | //
5 | // Created by caokun on 16/7/2.
6 | // Copyright © 2016年 caokun. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | typedef void (^TCPBlock)(id response, NSString *error);
12 |
13 | // TCP 请求接口类
14 | @interface TCPAPI : NSObject
15 |
16 | + (TCPAPI *)instance;
17 |
18 | // 登录请求,网络恢复调用该接口实现自动登录,被踢,用户主动退出登录,不能自动登录
19 | - (void)requestLogin:(NSString *)name password:(NSString *)psw completion:(TCPBlock)block;
20 |
21 | // 发送单个心跳包
22 | - (void)sendHeart;
23 |
24 | // 开启心跳,登录时开启即可,其他情况自动开启或关闭
25 | - (void)startHeartBeat;
26 |
27 | // 关闭心跳,退出时关闭,关闭后不会自动开启
28 | - (void)closeHeartBeat;
29 |
30 | // 请求股票排行版数据
31 | - (void)requestBlockWithcompletion:(TCPBlock)block;
32 |
33 | // 模拟收到踢人包
34 | - (void)receiveKick;
35 |
36 | @end
37 |
38 |
--------------------------------------------------------------------------------
/GCDAsyncSocket/ViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.h
3 | // GCDAsyncSocket
4 | //
5 | // Created by caokun on 16/7/5.
6 | // Copyright © 2016年 caokun. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface ViewController : UIViewController
12 |
13 |
14 | @end
15 |
16 |
--------------------------------------------------------------------------------
/GCDAsyncSocket/ViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.m
3 | // GCDAsyncSocket使用
4 | //
5 | // Created by caokun on 16/5/27.
6 | // Copyright © 2016年 caokun. All rights reserved.
7 | //
8 |
9 | #import "ViewController.h"
10 | #import "SocketManager.h"
11 | #import "TCPAPI.h"
12 | #import "NetWorkManager.h"
13 | #import "SpeedDectectManager.h"
14 |
15 | @interface ViewController ()
16 |
17 | @end
18 |
19 | @implementation ViewController
20 |
21 | - (void)viewDidLoad {
22 | [super viewDidLoad];
23 |
24 | }
25 |
26 | - (void)didReceiveMemoryWarning {
27 | [super didReceiveMemoryWarning];
28 |
29 | }
30 |
31 | - (IBAction)connectButton:(id)sender {
32 | [[SocketManager instance] connectAutomatic:nil];
33 | }
34 |
35 | - (IBAction)disconnectButton:(id)sender {
36 | [[SocketManager instance] disConnect];
37 | }
38 |
39 | - (IBAction)heart:(id)sender {
40 | [[TCPAPI instance] sendHeart];
41 | }
42 |
43 | - (IBAction)TCPLogin:(id)sender {
44 | // 此处 tcp 请求可以在其他线程,以0.3秒/次的速度请求,模拟网络断开或连上
45 | // 用户名跟密码由于是公司的账号,不敢随便公布了
46 | [[TCPAPI instance] requestLogin:@"用户名" password:@"密码" completion:^(id response, NSString *error) {
47 | if (error == nil) {
48 | NSDictionary *dic = (NSDictionary *)response;
49 | NSLog(@"%@", dic);
50 | } else {
51 | NSLog(@"登录失败");
52 | }
53 | }];
54 | }
55 |
56 | // 普通应用层请求
57 | - (IBAction)requestTcp:(id)sender {
58 | [[TCPAPI instance] requestBlockWithcompletion:^(id response, NSString *error) {
59 | if (error == nil) {
60 | NSArray *array = (NSArray *)response;
61 | NSLog(@"%@", array);
62 | } else {
63 | NSLog(@"UI层:%@", error);
64 | }
65 | }];
66 | }
67 |
68 | // 模拟 TCPAPI 类收到踢人包
69 | - (IBAction)kick:(id)sender {
70 | [[TCPAPI instance] receiveKick];
71 | }
72 |
73 | @end
74 |
75 |
--------------------------------------------------------------------------------
/GCDAsyncSocket/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // GCDAsyncSocket
4 | //
5 | // Created by caokun on 16/7/5.
6 | // Copyright © 2016年 caokun. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "AppDelegate.h"
11 |
12 | int main(int argc, char * argv[]) {
13 | @autoreleasepool {
14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # AsyncSocket
2 | 我在工作中用GCDAsyncSocket封装的一套TCP网络服务框架,用在公司的股票产品上
3 |
4 | 股票场景有实时性,所以通讯协议必须走socket,股票数据量大,传输协议用谷歌的ProtoBuffer,序列化速度快,数据压缩比高,省流量
5 |
6 | 因为是公司的产品用的,我删掉了相关的账号和公司内部的ip,所以能看到程序实现思路,而不能运行了
7 |
8 |
9 | 文件说明
10 |
11 | ViewController.h 测试的界面
12 |
13 | TCPAPI.h 这个类负责tcp请求封装,心跳机制,tcp打包拆包,自动重登录,数据序列化
14 |
15 | SocketManager.h 这个类负责socket状态管理,掉线重连
16 |
17 | SpeedDectectManager.h 这个类负责客户端的负载均衡,测速服务
18 |
19 | NetWorkManager.h 判断网络状态
20 |
21 |
22 | 我把有状态的socket封装成了对应用层来说是无状态的,就像使用HTTP请求那样简单,它能够处理自动重连,自动TCP层的重登录,自动测速和负载均衡,包括一些缓存,能适应网络频繁断开连上的情况,具体细节写在注释中了,有兴趣的可以看看
23 |
24 | 整个TCP网络服务层逻辑,图片可能太小,建议从代码库中下载到本地查看
25 |
26 | 
27 |
28 |
29 | 如果您发现程序有问题,欢迎反馈,谢谢,我的QQ:657668857,或者邮箱657668857@qq.com
30 |
--------------------------------------------------------------------------------
/TCP网络服务层逻辑.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hehe520/AsyncSocket/5cbf92e8444376aa3a1423ece983649a682c3cc1/TCP网络服务层逻辑.png
--------------------------------------------------------------------------------