From 2f10127f85ebb4f81d64e195bee7731a40d00fa2 Mon Sep 17 00:00:00 2001 From: Jorge Canizales Date: Wed, 2 Sep 2015 21:55:37 -0700 Subject: Publish GRPCRequestHeaders as a protocol So we can make the property a dictionary later, by just extending NSMutableDictionary to conform to the protocol. --- src/objective-c/GRPCClient/GRPCCall.h | 17 ++- src/objective-c/GRPCClient/GRPCCall.m | 5 +- src/objective-c/GRPCClient/GRPCRequestHeaders.h | 52 --------- src/objective-c/GRPCClient/GRPCRequestHeaders.m | 120 --------------------- .../GRPCClient/private/GRPCRequestHeaders.h | 52 +++++++++ .../GRPCClient/private/GRPCRequestHeaders.m | 120 +++++++++++++++++++++ .../GRPCClient/private/GRPCWrappedCall.h | 5 +- .../GRPCClient/private/GRPCWrappedCall.m | 4 +- 8 files changed, 193 insertions(+), 182 deletions(-) delete mode 100644 src/objective-c/GRPCClient/GRPCRequestHeaders.h delete mode 100644 src/objective-c/GRPCClient/GRPCRequestHeaders.m create mode 100644 src/objective-c/GRPCClient/private/GRPCRequestHeaders.h create mode 100644 src/objective-c/GRPCClient/private/GRPCRequestHeaders.m diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index 1487001da5..fc274a095f 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -48,13 +48,26 @@ #import #import -#import "GRPCRequestHeaders.h" +#include // Keys used in |NSError|'s |userInfo| dictionary to store the response headers and trailers sent by // the server. extern id const kGRPCHeadersKey; extern id const kGRPCTrailersKey; +@protocol GRPCRequestHeaders + +@property(nonatomic, readonly) NSUInteger count; +@property(nonatomic, readonly) grpc_metadata *grpc_metadataArray; + +- (id)objectForKeyedSubscript:(NSString *)key; +- (void)setObject:(id)obj forKeyedSubscript:(NSString *)key; + +- (void)removeAllObjects; +- (void)removeObjectForKey:(NSString *)key; + +@end + // Represents a single gRPC remote call. @interface GRPCCall : GRXWriter @@ -72,7 +85,7 @@ extern id const kGRPCTrailersKey; // // For convenience, the property is initialized to an empty NSMutableDictionary, and the setter // accepts (and copies) both mutable and immutable dictionaries. -- (GRPCRequestHeaders *)requestHeaders; // nonatomic +- (id)requestHeaders; // nonatomic - (void)setRequestHeaders:(NSDictionary *)requestHeaders; // nonatomic, copy // This dictionary is populated with the HTTP headers received from the server. This happens before diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index d5f775c6e6..1be753e688 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -37,6 +37,7 @@ #include #import +#import "private/GRPCRequestHeaders.h" #import "private/GRPCWrappedCall.h" #import "private/NSData+GRPC.h" #import "private/NSDictionary+GRPC.h" @@ -131,7 +132,7 @@ NSString * const kGRPCTrailersKey = @"io.grpc.TrailersKey"; #pragma mark Metadata -- (GRPCRequestHeaders *)requestHeaders { +- (id)requestHeaders { return _requestHeaders; } @@ -234,7 +235,7 @@ NSString * const kGRPCTrailersKey = @"io.grpc.TrailersKey"; #pragma mark Send headers -- (void)sendHeaders:(GRPCRequestHeaders *)headers { +- (void)sendHeaders:(id)headers { // TODO(jcanizales): Add error handlers for async failures [_wrappedCall startBatchWithOperations:@[[[GRPCOpSendMetadata alloc] initWithMetadata:headers handler:nil]]]; diff --git a/src/objective-c/GRPCClient/GRPCRequestHeaders.h b/src/objective-c/GRPCClient/GRPCRequestHeaders.h deleted file mode 100644 index 5a93f82cd8..0000000000 --- a/src/objective-c/GRPCClient/GRPCRequestHeaders.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * - * Copyright 2015, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#import -#include - -@class GRPCCall; - -@interface GRPCRequestHeaders : NSObject - -@property(nonatomic, readonly) NSUInteger count; -@property(nonatomic, readonly) grpc_metadata *grpc_metadataArray; - -- (instancetype)initWithCall:(GRPCCall *)call; - -- (id)objectForKeyedSubscript:(NSString *)key; -- (void)setObject:(id)obj forKeyedSubscript:(NSString *)key; - -- (void)removeAllObjects; -- (void)removeObjectForKey:(NSString *)aKey; - -@end \ No newline at end of file diff --git a/src/objective-c/GRPCClient/GRPCRequestHeaders.m b/src/objective-c/GRPCClient/GRPCRequestHeaders.m deleted file mode 100644 index d4bbbdf84a..0000000000 --- a/src/objective-c/GRPCClient/GRPCRequestHeaders.m +++ /dev/null @@ -1,120 +0,0 @@ -/* - * - * Copyright 2015, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#import "GRPCRequestHeaders.h" - -#import - -#import "GRPCCall.h" -#import "NSDictionary+GRPC.h" - -// Used by the setters. -static NSString* NormalizeKey(NSString* key) { - if (!key) { - [NSException raise:NSInvalidArgumentException format:@"Key cannot be nil"]; - } - if (![key canBeConvertedToEncoding:NSASCIIStringEncoding]) { - [NSException raise:NSInvalidArgumentException - format:@"Key %@ contains non-ASCII characters", key]; - } - return key.lowercaseString; -} - -// Precondition: key isn't nil. -static void CheckKeyValuePairIsValid(NSString *key, id value) { - if ([key hasSuffix:@"-bin"]) { - if (![value isKindOfClass:NSData.class]) { - [NSException raise:NSInvalidArgumentException - format:@"Expected NSData value for header %@ ending in \"-bin\", " - @"instead got %@", key, value]; - } - } else { - if (![value isKindOfClass:NSString.class]) { - [NSException raise:NSInvalidArgumentException - format:@"Expected NSString value for header %@ not ending in \"-bin\", " - @"instead got %@", key, value]; - } - } -} - -@implementation GRPCRequestHeaders { - __weak GRPCCall *_call; - NSMutableDictionary *_proxy; -} - -- (instancetype)initWithCall:(GRPCCall *)call { - if ((self = [super init])) { - _call = call; - _proxy = [NSMutableDictionary dictionary]; - } - return self; -} - -- (void)checkCallIsNotStarted { - if (_call.state != GRXWriterStateNotStarted) { - [NSException raise:@"Invalid modification" - format:@"Cannot modify request headers after call is started"]; - } -} - -- (id)objectForKeyedSubscript:(NSString *)key { - return _proxy[key.lowercaseString]; -} - -- (void)setObject:(id)obj forKeyedSubscript:(NSString *)key { - [self checkCallIsNotStarted]; - key = NormalizeKey(key); - CheckKeyValuePairIsValid(key, obj); - _proxy[key] = obj; -} - -- (void)removeObjectForKey:(NSString *)key { - [self checkCallIsNotStarted]; - [_proxy removeObjectForKey:NormalizeKey(key)]; -} - -- (void)removeAllObjects { - [self checkCallIsNotStarted]; - [_proxy removeAllObjects]; -} - -// TODO(jcanizales): Just forward all invocations? - -- (NSUInteger)count { - return _proxy.count; -} - -- (grpc_metadata *)grpc_metadataArray { - return _proxy.grpc_metadataArray; -} -@end \ No newline at end of file diff --git a/src/objective-c/GRPCClient/private/GRPCRequestHeaders.h b/src/objective-c/GRPCClient/private/GRPCRequestHeaders.h new file mode 100644 index 0000000000..066f71a8f6 --- /dev/null +++ b/src/objective-c/GRPCClient/private/GRPCRequestHeaders.h @@ -0,0 +1,52 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#import +#include + +#import "GRPCCall.h" + +@interface GRPCRequestHeaders : NSObject + +@property(nonatomic, readonly) NSUInteger count; +@property(nonatomic, readonly) grpc_metadata *grpc_metadataArray; + +- (instancetype)initWithCall:(GRPCCall *)call; + +- (id)objectForKeyedSubscript:(NSString *)key; +- (void)setObject:(id)obj forKeyedSubscript:(NSString *)key; + +- (void)removeAllObjects; +- (void)removeObjectForKey:(NSString *)aKey; + +@end \ No newline at end of file diff --git a/src/objective-c/GRPCClient/private/GRPCRequestHeaders.m b/src/objective-c/GRPCClient/private/GRPCRequestHeaders.m new file mode 100644 index 0000000000..d4bbbdf84a --- /dev/null +++ b/src/objective-c/GRPCClient/private/GRPCRequestHeaders.m @@ -0,0 +1,120 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#import "GRPCRequestHeaders.h" + +#import + +#import "GRPCCall.h" +#import "NSDictionary+GRPC.h" + +// Used by the setters. +static NSString* NormalizeKey(NSString* key) { + if (!key) { + [NSException raise:NSInvalidArgumentException format:@"Key cannot be nil"]; + } + if (![key canBeConvertedToEncoding:NSASCIIStringEncoding]) { + [NSException raise:NSInvalidArgumentException + format:@"Key %@ contains non-ASCII characters", key]; + } + return key.lowercaseString; +} + +// Precondition: key isn't nil. +static void CheckKeyValuePairIsValid(NSString *key, id value) { + if ([key hasSuffix:@"-bin"]) { + if (![value isKindOfClass:NSData.class]) { + [NSException raise:NSInvalidArgumentException + format:@"Expected NSData value for header %@ ending in \"-bin\", " + @"instead got %@", key, value]; + } + } else { + if (![value isKindOfClass:NSString.class]) { + [NSException raise:NSInvalidArgumentException + format:@"Expected NSString value for header %@ not ending in \"-bin\", " + @"instead got %@", key, value]; + } + } +} + +@implementation GRPCRequestHeaders { + __weak GRPCCall *_call; + NSMutableDictionary *_proxy; +} + +- (instancetype)initWithCall:(GRPCCall *)call { + if ((self = [super init])) { + _call = call; + _proxy = [NSMutableDictionary dictionary]; + } + return self; +} + +- (void)checkCallIsNotStarted { + if (_call.state != GRXWriterStateNotStarted) { + [NSException raise:@"Invalid modification" + format:@"Cannot modify request headers after call is started"]; + } +} + +- (id)objectForKeyedSubscript:(NSString *)key { + return _proxy[key.lowercaseString]; +} + +- (void)setObject:(id)obj forKeyedSubscript:(NSString *)key { + [self checkCallIsNotStarted]; + key = NormalizeKey(key); + CheckKeyValuePairIsValid(key, obj); + _proxy[key] = obj; +} + +- (void)removeObjectForKey:(NSString *)key { + [self checkCallIsNotStarted]; + [_proxy removeObjectForKey:NormalizeKey(key)]; +} + +- (void)removeAllObjects { + [self checkCallIsNotStarted]; + [_proxy removeAllObjects]; +} + +// TODO(jcanizales): Just forward all invocations? + +- (NSUInteger)count { + return _proxy.count; +} + +- (grpc_metadata *)grpc_metadataArray { + return _proxy.grpc_metadataArray; +} +@end \ No newline at end of file diff --git a/src/objective-c/GRPCClient/private/GRPCWrappedCall.h b/src/objective-c/GRPCClient/private/GRPCWrappedCall.h index ba34c0a6e7..9147ba0816 100644 --- a/src/objective-c/GRPCClient/private/GRPCWrappedCall.h +++ b/src/objective-c/GRPCClient/private/GRPCWrappedCall.h @@ -35,8 +35,7 @@ #include #import "GRPCChannel.h" - -@class GRPCRequestHeaders; +#import "GRPCCall.h" @interface GRPCOperation : NSObject @property(nonatomic, readonly) grpc_op op; @@ -46,7 +45,7 @@ @interface GRPCOpSendMetadata : GRPCOperation -- (instancetype)initWithMetadata:(GRPCRequestHeaders *)metadata +- (instancetype)initWithMetadata:(id)metadata handler:(void(^)())handler NS_DESIGNATED_INITIALIZER; @end diff --git a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m index 3cb5613bd0..1f8c647fa6 100644 --- a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m +++ b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m @@ -38,8 +38,6 @@ #include #include -#import "GRPCRequestHeaders.h" - #import "GRPCCompletionQueue.h" #import "GRPCHost.h" #import "NSDictionary+GRPC.h" @@ -67,7 +65,7 @@ return [self initWithMetadata:nil handler:nil]; } -- (instancetype)initWithMetadata:(GRPCRequestHeaders *)metadata handler:(void (^)())handler { +- (instancetype)initWithMetadata:(id)metadata handler:(void (^)())handler { if (self = [super init]) { _op.op = GRPC_OP_SEND_INITIAL_METADATA; _op.data.send_initial_metadata.count = metadata.count; -- cgit v1.2.3