diff options
author | Michael Lumish <mlumish@google.com> | 2015-07-17 13:45:01 -0700 |
---|---|---|
committer | Michael Lumish <mlumish@google.com> | 2015-07-17 13:45:01 -0700 |
commit | 048fc2f04fc5802621eb4703a14f49625265f498 (patch) | |
tree | 993175e5250288770d1a0a5834746ddae14c0acf | |
parent | fb5ce3dbeaedd89e4621eb903db3af663e7a3698 (diff) | |
parent | 29f55d5655dc095205f8d02e01dcd0e2583c39eb (diff) |
Merge pull request #2488 from jcanizales/subclass-grxwriter
Subclass GRXWriter instead of conforming to its protocol
22 files changed, 210 insertions, 139 deletions
diff --git a/src/compiler/objective_c_generator.cc b/src/compiler/objective_c_generator.cc index 2a74a3b340..711d0d5870 100644 --- a/src/compiler/objective_c_generator.cc +++ b/src/compiler/objective_c_generator.cc @@ -67,7 +67,7 @@ void PrintMethodSignature(Printer *printer, const MethodDescriptor *method, printer->Print(vars, "- ($return_type$)$method_name$With"); if (method->client_streaming()) { - printer->Print("RequestsWriter:(id<GRXWriter>)requestWriter"); + printer->Print("RequestsWriter:(GRXWriter *)requestWriter"); } else { printer->Print(vars, "Request:($request_class$ *)request"); } diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index cba53fa2f6..4a8b7fff48 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -52,7 +52,7 @@ extern id const kGRPCStatusMetadataKey; // Represents a single gRPC remote call. -@interface GRPCCall : NSObject<GRXWriter> +@interface GRPCCall : GRXWriter // These HTTP headers will be passed to the server as part of this call. Each HTTP header is a // name-value pair with string names and either string or binary values. @@ -89,7 +89,7 @@ extern id const kGRPCStatusMetadataKey; // To finish a call right away, invoke cancel. - (instancetype)initWithHost:(NSString *)host path:(NSString *)path - requestsWriter:(id<GRXWriter>)requestsWriter NS_DESIGNATED_INITIALIZER; + requestsWriter:(GRXWriter *)requestsWriter NS_DESIGNATED_INITIALIZER; // Finishes the request side of this call, notifies the server that the RPC // should be cancelled, and finishes the response side of the call with an error diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 4ac4e4d37f..53e5abe177 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -79,7 +79,7 @@ NSString * const kGRPCStatusMetadataKey = @"io.grpc.StatusMetadataKey"; // all. This wrapper over our actual writeable ensures thread-safety and // correct ordering. GRPCDelegateWrapper *_responseWriteable; - id<GRXWriter> _requestWriter; + GRXWriter *_requestWriter; NSMutableDictionary *_requestMetadata; NSMutableDictionary *_responseMetadata; @@ -94,7 +94,7 @@ NSString * const kGRPCStatusMetadataKey = @"io.grpc.StatusMetadataKey"; // Designated initializer - (instancetype)initWithHost:(NSString *)host path:(NSString *)path - requestsWriter:(id<GRXWriter>)requestWriter { + requestsWriter:(GRXWriter *)requestWriter { if (!host || !path) { [NSException raise:NSInvalidArgumentException format:@"Neither host nor method can be nil."]; } diff --git a/src/objective-c/GRPCClient/private/GRPCDelegateWrapper.h b/src/objective-c/GRPCClient/private/GRPCDelegateWrapper.h index 1ef245fe37..9a30a2f966 100644 --- a/src/objective-c/GRPCClient/private/GRPCDelegateWrapper.h +++ b/src/objective-c/GRPCClient/private/GRPCDelegateWrapper.h @@ -33,8 +33,9 @@ #import <Foundation/Foundation.h> +#import <RxLibrary/GRXWriter.h> + @protocol GRXWriteable; -@protocol GRXWriter; // This is a thread-safe wrapper over a GRXWriteable instance. It lets one // enqueue calls to a GRXWriteable instance for the main thread, guaranteeing @@ -54,7 +55,7 @@ // writesFinishedWithError: is sent to the writeable, and released after that. // This is used to create a retain cycle that keeps both objects alive until the // writing is explicitly finished. -- (instancetype)initWithWriteable:(id<GRXWriteable>)writeable writer:(id<GRXWriter>)writer +- (instancetype)initWithWriteable:(id<GRXWriteable>)writeable writer:(GRXWriter *)writer NS_DESIGNATED_INITIALIZER; // Enqueues writeValue: to be sent to the writeable in the main thread. diff --git a/src/objective-c/GRPCClient/private/GRPCDelegateWrapper.m b/src/objective-c/GRPCClient/private/GRPCDelegateWrapper.m index 59c0565494..294cfb7e23 100644 --- a/src/objective-c/GRPCClient/private/GRPCDelegateWrapper.m +++ b/src/objective-c/GRPCClient/private/GRPCDelegateWrapper.m @@ -38,7 +38,7 @@ @interface GRPCDelegateWrapper () // These are atomic so that cancellation can nillify them from any thread. @property(atomic, strong) id<GRXWriteable> writeable; -@property(atomic, strong) id<GRXWriter> writer; +@property(atomic, strong) GRXWriter *writer; @end @implementation GRPCDelegateWrapper { @@ -52,7 +52,7 @@ } // Designated initializer -- (instancetype)initWithWriteable:(id<GRXWriteable>)writeable writer:(id<GRXWriter>)writer { +- (instancetype)initWithWriteable:(id<GRXWriteable>)writeable writer:(GRXWriter *)writer { if (self = [super init]) { _writeableQueue = dispatch_get_main_queue(); _writeable = writeable; diff --git a/src/objective-c/ProtoRPC/ProtoRPC.h b/src/objective-c/ProtoRPC/ProtoRPC.h index fcc0a507fe..bd926b7328 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.h +++ b/src/objective-c/ProtoRPC/ProtoRPC.h @@ -40,7 +40,7 @@ - (instancetype)initWithHost:(NSString *)host method:(ProtoMethod *)method - requestsWriter:(id<GRXWriter>)requestsWriter + requestsWriter:(GRXWriter *)requestsWriter responseClass:(Class)responseClass responsesWriteable:(id<GRXWriteable>)responsesWriteable NS_DESIGNATED_INITIALIZER; diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index fe3ccf0541..889d71a308 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -35,7 +35,6 @@ #import <GPBProtocolBuffers.h> #import <RxLibrary/GRXWriteable.h> -#import <RxLibrary/GRXWriter.h> #import <RxLibrary/GRXWriter+Transformations.h> @implementation ProtoRPC { @@ -46,7 +45,7 @@ #pragma clang diagnostic ignored "-Wobjc-designated-initializers" - (instancetype)initWithHost:(NSString *)host path:(NSString *)path - requestsWriter:(id<GRXWriter>)requestsWriter { + requestsWriter:(GRXWriter *)requestsWriter { [NSException raise:NSInvalidArgumentException format:@"Please use ProtoRPC's designated initializer instead."]; return nil; @@ -56,7 +55,7 @@ // Designated initializer - (instancetype)initWithHost:(NSString *)host method:(ProtoMethod *)method - requestsWriter:(id<GRXWriter>)requestsWriter + requestsWriter:(GRXWriter *)requestsWriter responseClass:(Class)responseClass responsesWriteable:(id<GRXWriteable>)responsesWriteable { // Because we can't tell the type system to constrain the class, we need to check at runtime: @@ -65,12 +64,11 @@ format:@"A protobuf class to parse the responses must be provided."]; } // A writer that serializes the proto messages to send. - id<GRXWriter> bytesWriter = - [[[GRXWriter alloc] initWithWriter:requestsWriter] map:^id(GPBMessage *proto) { - // TODO(jcanizales): Fail with an understandable error message if the requestsWriter isn't - // sending GPBMessages. - return [proto data]; - }]; + GRXWriter *bytesWriter = [requestsWriter map:^id(GPBMessage *proto) { + // TODO(jcanizales): Fail with an understandable error message if the requestsWriter isn't + // sending GPBMessages. + return [proto data]; + }]; if ((self = [super initWithHost:host path:method.HTTPPath requestsWriter:bytesWriter])) { // A writeable that parses the proto messages received. _responseWriteable = [[GRXWriteable alloc] initWithValueHandler:^(NSData *value) { diff --git a/src/objective-c/ProtoRPC/ProtoService.h b/src/objective-c/ProtoRPC/ProtoService.h index c5ef820f48..2e8cb33696 100644 --- a/src/objective-c/ProtoRPC/ProtoService.h +++ b/src/objective-c/ProtoRPC/ProtoService.h @@ -35,7 +35,7 @@ @class ProtoRPC; @protocol GRXWriteable; -@protocol GRXWriter; +@class GRXWriter; @interface ProtoService : NSObject - (instancetype)initWithHost:(NSString *)host @@ -43,7 +43,7 @@ serviceName:(NSString *)serviceName NS_DESIGNATED_INITIALIZER; - (ProtoRPC *)RPCToMethod:(NSString *)method - requestsWriter:(id<GRXWriter>)requestsWriter + requestsWriter:(GRXWriter *)requestsWriter responseClass:(Class)responseClass responsesWriteable:(id<GRXWriteable>)responsesWriteable; @end diff --git a/src/objective-c/ProtoRPC/ProtoService.m b/src/objective-c/ProtoRPC/ProtoService.m index d7c5b6a850..fccc6aadc9 100644 --- a/src/objective-c/ProtoRPC/ProtoService.m +++ b/src/objective-c/ProtoRPC/ProtoService.m @@ -66,7 +66,7 @@ } - (ProtoRPC *)RPCToMethod:(NSString *)method - requestsWriter:(id<GRXWriter>)requestsWriter + requestsWriter:(GRXWriter *)requestsWriter responseClass:(Class)responseClass responsesWriteable:(id<GRXWriteable>)responsesWriteable { ProtoMethod *methodName = [[ProtoMethod alloc] initWithPackage:_packageName diff --git a/src/objective-c/RxLibrary/GRXBufferedPipe.h b/src/objective-c/RxLibrary/GRXBufferedPipe.h index 5e876a73bf..b6296e1ed7 100644 --- a/src/objective-c/RxLibrary/GRXBufferedPipe.h +++ b/src/objective-c/RxLibrary/GRXBufferedPipe.h @@ -51,7 +51,7 @@ // pipe will keep buffering all data written to it, your application could run out of memory and // crash. If you want to react to flow control signals to prevent that, instead of using this class // you can implement an object that conforms to GRXWriter. -@interface GRXBufferedPipe : NSObject<GRXWriteable, GRXWriter> +@interface GRXBufferedPipe : GRXWriter<GRXWriteable> // Convenience constructor. + (instancetype)pipe; diff --git a/src/objective-c/RxLibrary/GRXForwardingWriter.h b/src/objective-c/RxLibrary/GRXForwardingWriter.h new file mode 100644 index 0000000000..d004333d2b --- /dev/null +++ b/src/objective-c/RxLibrary/GRXForwardingWriter.h @@ -0,0 +1,43 @@ +/* + * + * 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 "GRXWriter.h" + +// A "proxy" class that simply forwards values, completion, and errors from its +// input writer to its writeable. +// It is useful as a superclass for pipes that act as a transformation of their +// input writer, and for classes that represent objects with input and +// output sequences of values, like an RPC. +@interface GRXForwardingWriter : GRXWriter +- (instancetype)initWithWriter:(GRXWriter *)writer NS_DESIGNATED_INITIALIZER; +@end diff --git a/src/objective-c/RxLibrary/GRXForwardingWriter.m b/src/objective-c/RxLibrary/GRXForwardingWriter.m new file mode 100644 index 0000000000..2342f51ab3 --- /dev/null +++ b/src/objective-c/RxLibrary/GRXForwardingWriter.m @@ -0,0 +1,112 @@ +/* + * + * 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 "GRXForwardingWriter.h" + +@interface GRXForwardingWriter () <GRXWriteable> +@end + +@implementation GRXForwardingWriter { + GRXWriter *_writer; + id<GRXWriteable> _writeable; +} + +- (instancetype)init { + return [self initWithWriter:nil]; +} + +// Designated initializer +- (instancetype)initWithWriter:(GRXWriter *)writer { + if (!writer) { + [NSException raise:NSInvalidArgumentException format:@"writer can't be nil."]; + } + if ((self = [super init])) { + _writer = writer; + } + return self; +} + +// This is used to send a completion or an error to the writeable. It nillifies +// our reference to it in order to guarantee no more messages are sent to it, +// and to release it. +- (void)finishOutputWithError:(NSError *)errorOrNil { + id<GRXWriteable> writeable = _writeable; + _writeable = nil; + [writeable writesFinishedWithError:errorOrNil]; +} + +// This is used to stop the input writer. It nillifies our reference to it +// to release it. +- (void)finishInput { + GRXWriter *writer = _writer; + _writer = nil; + writer.state = GRXWriterStateFinished; +} + +#pragma mark GRXWriteable implementation + +- (void)writeValue:(id)value { + [_writeable writeValue:value]; +} + +- (void)writesFinishedWithError:(NSError *)errorOrNil { + _writer = nil; + [self finishOutputWithError:errorOrNil]; +} + +#pragma mark GRXWriter implementation + +- (GRXWriterState)state { + return _writer ? _writer.state : GRXWriterStateFinished; +} + +- (void)setState:(GRXWriterState)state { + if (state == GRXWriterStateFinished) { + _writeable = nil; + [self finishInput]; + } else { + _writer.state = state; + } +} + +- (void)startWithWriteable:(id<GRXWriteable>)writeable { + _writeable = writeable; + [_writer startWithWriteable:self]; +} + +- (void)finishWithError:(NSError *)errorOrNil { + [self finishOutputWithError:errorOrNil]; + [self finishInput]; +} + +@end diff --git a/src/objective-c/RxLibrary/GRXImmediateWriter.h b/src/objective-c/RxLibrary/GRXImmediateWriter.h index f86d38dcd8..b171f0c760 100644 --- a/src/objective-c/RxLibrary/GRXImmediateWriter.h +++ b/src/objective-c/RxLibrary/GRXImmediateWriter.h @@ -40,15 +40,15 @@ // // Unless the writeable callback pauses them or stops them early, these writers will do all their // interactions with the writeable before the start method returns. -@interface GRXImmediateWriter : NSObject<GRXWriter> +@interface GRXImmediateWriter : GRXWriter // Returns a writer that pulls values from the passed NSEnumerator instance and pushes them to // its writeable. The NSEnumerator is released when it finishes. -+ (id<GRXWriter>)writerWithEnumerator:(NSEnumerator *)enumerator; ++ (GRXWriter *)writerWithEnumerator:(NSEnumerator *)enumerator; // Returns a writer that pushes to its writeable the successive values returned by the passed // block. When the block first returns nil, it is released. -+ (id<GRXWriter>)writerWithValueSupplier:(id (^)())block; ++ (GRXWriter *)writerWithValueSupplier:(id (^)())block; // Returns a writer that iterates over the values of the passed container and pushes them to // its writeable. The container is released when the iteration is over. @@ -56,18 +56,18 @@ // Note that the usual speed gain of NSFastEnumeration over NSEnumerator results from not having to // call one method per element. Because GRXWriteable instances accept values one by one, that speed // gain doesn't happen here. -+ (id<GRXWriter>)writerWithContainer:(id<NSFastEnumeration>)container; ++ (GRXWriter *)writerWithContainer:(id<NSFastEnumeration>)container; // Returns a writer that sends the passed value to its writeable and then finishes (releasing the // value). -+ (id<GRXWriter>)writerWithValue:(id)value; ++ (GRXWriter *)writerWithValue:(id)value; // Returns a writer that, as part of its start method, sends the passed error to the writeable // (then releasing the error). -+ (id<GRXWriter>)writerWithError:(NSError *)error; ++ (GRXWriter *)writerWithError:(NSError *)error; // Returns a writer that, as part of its start method, finishes immediately without sending any // values to its writeable. -+ (id<GRXWriter>)emptyWriter; ++ (GRXWriter *)emptyWriter; @end diff --git a/src/objective-c/RxLibrary/GRXImmediateWriter.m b/src/objective-c/RxLibrary/GRXImmediateWriter.m index 0b4979872e..b6d2b2cac0 100644 --- a/src/objective-c/RxLibrary/GRXImmediateWriter.m +++ b/src/objective-c/RxLibrary/GRXImmediateWriter.m @@ -63,19 +63,19 @@ return [[self alloc] initWithEnumerator:enumerator error:errorOrNil]; } -+ (id<GRXWriter>)writerWithEnumerator:(NSEnumerator *)enumerator { ++ (GRXWriter *)writerWithEnumerator:(NSEnumerator *)enumerator { return [self writerWithEnumerator:enumerator error:nil]; } -+ (id<GRXWriter>)writerWithValueSupplier:(id (^)())block { ++ (GRXWriter *)writerWithValueSupplier:(id (^)())block { return [self writerWithEnumerator:[NSEnumerator grx_enumeratorWithValueSupplier:block]]; } -+ (id<GRXWriter>)writerWithContainer:(id<NSFastEnumeration>)container { ++ (GRXWriter *)writerWithContainer:(id<NSFastEnumeration>)container { return [self writerWithEnumerator:[NSEnumerator grx_enumeratorWithContainer:container]];; } -+ (id<GRXWriter>)writerWithValue:(id)value { ++ (GRXWriter *)writerWithValue:(id)value { if (value) { return [self writerWithEnumerator:[NSEnumerator grx_enumeratorWithSingleValue:value]]; } else { @@ -83,7 +83,7 @@ } } -+ (id<GRXWriter>)writerWithError:(NSError *)error { ++ (GRXWriter *)writerWithError:(NSError *)error { if (error) { return [self writerWithEnumerator:nil error:error]; } else { @@ -91,7 +91,7 @@ } } -+ (id<GRXWriter>)emptyWriter { ++ (GRXWriter *)emptyWriter { static GRXImmediateWriter *emptyWriter; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ diff --git a/src/objective-c/RxLibrary/GRXWriter+Immediate.m b/src/objective-c/RxLibrary/GRXWriter+Immediate.m index 39c54f86ec..1d55eb3529 100644 --- a/src/objective-c/RxLibrary/GRXWriter+Immediate.m +++ b/src/objective-c/RxLibrary/GRXWriter+Immediate.m @@ -38,27 +38,27 @@ @implementation GRXWriter (Immediate) + (instancetype)writerWithEnumerator:(NSEnumerator *)enumerator { - return [[self alloc] initWithWriter:[GRXImmediateWriter writerWithEnumerator:enumerator]]; + return [GRXImmediateWriter writerWithEnumerator:enumerator]; } + (instancetype)writerWithValueSupplier:(id (^)())block { - return [[self alloc] initWithWriter:[GRXImmediateWriter writerWithValueSupplier:block]]; + return [GRXImmediateWriter writerWithValueSupplier:block]; } + (instancetype)writerWithContainer:(id<NSFastEnumeration>)container { - return [[self alloc] initWithWriter:[GRXImmediateWriter writerWithContainer:container]]; + return [GRXImmediateWriter writerWithContainer:container]; } + (instancetype)writerWithValue:(id)value { - return [[self alloc] initWithWriter:[GRXImmediateWriter writerWithValue:value]]; + return [GRXImmediateWriter writerWithValue:value]; } + (instancetype)writerWithError:(NSError *)error { - return [[self alloc] initWithWriter:[GRXImmediateWriter writerWithError:error]]; + return [GRXImmediateWriter writerWithError:error]; } + (instancetype)emptyWriter { - return [[self alloc] initWithWriter:[GRXImmediateWriter emptyWriter]]; + return [GRXImmediateWriter emptyWriter]; } @end diff --git a/src/objective-c/RxLibrary/GRXWriter.h b/src/objective-c/RxLibrary/GRXWriter.h index dcf44e3143..5d6e1a472a 100644 --- a/src/objective-c/RxLibrary/GRXWriter.h +++ b/src/objective-c/RxLibrary/GRXWriter.h @@ -85,7 +85,7 @@ typedef NS_ENUM(NSInteger, GRXWriterState) { // Unless otherwise indicated by a conforming class, no messages should be sent // concurrently to a GRXWriter. I.e., conforming classes aren't required to // be thread-safe. -@protocol GRXWriter <NSObject> +@interface GRXWriter : NSObject // This property can be used to query the current state of the writer, which // determines how it might currently use its writeable. Some state transitions can @@ -116,12 +116,3 @@ typedef NS_ENUM(NSInteger, GRXWriterState) { // can't remember the details in the presence of concurrency. - (void)finishWithError:(NSError *)errorOrNil; @end - -// A "proxy" class that simply forwards values, completion, and errors from its -// input writer to its writeable. -// It is useful as a superclass for pipes that act as a transformation of their -// input writer, and for classes that represent objects with input and -// output sequences of values, like an RPC. -@interface GRXWriter : NSObject<GRXWriter> -- (instancetype)initWithWriter:(id<GRXWriter>)writer NS_DESIGNATED_INITIALIZER; -@end diff --git a/src/objective-c/RxLibrary/GRXWriter.m b/src/objective-c/RxLibrary/GRXWriter.m index cc14383560..019fcbd785 100644 --- a/src/objective-c/RxLibrary/GRXWriter.m +++ b/src/objective-c/RxLibrary/GRXWriter.m @@ -33,80 +33,6 @@ #import "GRXWriter.h" -@interface GRXWriter () <GRXWriteable> -@end - -@implementation GRXWriter { - id<GRXWriter> _writer; - id<GRXWriteable> _writeable; -} - -- (instancetype)init { - return [self initWithWriter:nil]; -} - -// Designated initializer -- (instancetype)initWithWriter:(id<GRXWriter>)writer { - if (!writer) { - [NSException raise:NSInvalidArgumentException format:@"writer can't be nil."]; - } - if ((self = [super init])) { - _writer = writer; - } - return self; -} - -// This is used to send a completion or an error to the writeable. It nillifies -// our reference to it in order to guarantee no more messages are sent to it, -// and to release it. -- (void)finishOutputWithError:(NSError *)errorOrNil { - id<GRXWriteable> writeable = _writeable; - _writeable = nil; - [writeable writesFinishedWithError:errorOrNil]; -} - -// This is used to stop the input writer. It nillifies our reference to it -// to release it. -- (void)finishInput { - id<GRXWriter> writer = _writer; - _writer = nil; - writer.state = GRXWriterStateFinished; -} - -#pragma mark GRXWriteable implementation - -- (void)writeValue:(id)value { - [_writeable writeValue:value]; -} - -- (void)writesFinishedWithError:(NSError *)errorOrNil { - _writer = nil; - [self finishOutputWithError:errorOrNil]; -} - -#pragma mark GRXWriter implementation - -- (GRXWriterState)state { - return _writer ? _writer.state : GRXWriterStateFinished; -} - -- (void)setState:(GRXWriterState)state { - if (state == GRXWriterStateFinished) { - _writeable = nil; - [self finishInput]; - } else { - _writer.state = state; - } -} - -- (void)startWithWriteable:(id<GRXWriteable>)writeable { - _writeable = writeable; - [_writer startWithWriteable:self]; -} - -- (void)finishWithError:(NSError *)errorOrNil { - [self finishOutputWithError:errorOrNil]; - [self finishInput]; -} +@implementation GRXWriter @end diff --git a/src/objective-c/RxLibrary/transformations/GRXMappingWriter.h b/src/objective-c/RxLibrary/transformations/GRXMappingWriter.h index 55f6f82f20..43b8706864 100644 --- a/src/objective-c/RxLibrary/transformations/GRXMappingWriter.h +++ b/src/objective-c/RxLibrary/transformations/GRXMappingWriter.h @@ -31,10 +31,10 @@ * */ -#import "RxLibrary/GRXWriter.h" +#import "RxLibrary/GRXForwardingWriter.h" // A "proxy" writer that transforms all the values of its input writer by using a mapping function. -@interface GRXMappingWriter : GRXWriter -- (instancetype)initWithWriter:(id<GRXWriter>)writer map:(id (^)(id value))map +@interface GRXMappingWriter : GRXForwardingWriter +- (instancetype)initWithWriter:(GRXWriter *)writer map:(id (^)(id value))map NS_DESIGNATED_INITIALIZER; @end diff --git a/src/objective-c/RxLibrary/transformations/GRXMappingWriter.m b/src/objective-c/RxLibrary/transformations/GRXMappingWriter.m index 2cdfea1b67..f3242e4fa9 100644 --- a/src/objective-c/RxLibrary/transformations/GRXMappingWriter.m +++ b/src/objective-c/RxLibrary/transformations/GRXMappingWriter.m @@ -37,19 +37,19 @@ static id (^kIdentity)(id value) = ^id(id value) { return value; }; -@interface GRXWriter () <GRXWriteable> +@interface GRXForwardingWriter () <GRXWriteable> @end @implementation GRXMappingWriter { id (^_map)(id value); } -- (instancetype)initWithWriter:(id<GRXWriter>)writer { +- (instancetype)initWithWriter:(GRXWriter *)writer { return [self initWithWriter:writer map:nil]; } // Designated initializer -- (instancetype)initWithWriter:(id<GRXWriter>)writer map:(id (^)(id value))map { +- (instancetype)initWithWriter:(GRXWriter *)writer map:(id (^)(id value))map { if ((self = [super initWithWriter:writer])) { _map = map ?: kIdentity; } diff --git a/src/objective-c/tests/GRPCClientTests.m b/src/objective-c/tests/GRPCClientTests.m index 2e03ad88a8..3210ad7050 100644 --- a/src/objective-c/tests/GRPCClientTests.m +++ b/src/objective-c/tests/GRPCClientTests.m @@ -120,7 +120,7 @@ static ProtoMethod *kUnaryCallMethod; request.responseSize = 100; request.fillUsername = YES; request.fillOauthScope = YES; - id<GRXWriter> requestsWriter = [GRXWriter writerWithValue:[request data]]; + GRXWriter *requestsWriter = [GRXWriter writerWithValue:[request data]]; GRPCCall *call = [[GRPCCall alloc] initWithHost:kHostAddress path:kUnaryCallMethod.HTTPPath @@ -150,7 +150,7 @@ static ProtoMethod *kUnaryCallMethod; RMTSimpleRequest *request = [RMTSimpleRequest message]; request.fillUsername = YES; request.fillOauthScope = YES; - id<GRXWriter> requestsWriter = [GRXWriter writerWithValue:[request data]]; + GRXWriter *requestsWriter = [GRXWriter writerWithValue:[request data]]; GRPCCall *call = [[GRPCCall alloc] initWithHost:kHostAddress path:kUnaryCallMethod.HTTPPath diff --git a/src/objective-c/tests/InteropTests.m b/src/objective-c/tests/InteropTests.m index 38fc65839c..501f33317a 100644 --- a/src/objective-c/tests/InteropTests.m +++ b/src/objective-c/tests/InteropTests.m @@ -143,7 +143,7 @@ RMTStreamingInputCallRequest *request4 = [RMTStreamingInputCallRequest message]; request4.payload.body = [NSMutableData dataWithLength:45904]; - id<GRXWriter> writer = [GRXWriter writerWithContainer:@[request1, request2, request3, request4]]; + GRXWriter *writer = [GRXWriter writerWithContainer:@[request1, request2, request3, request4]]; [_service streamingInputCallWithRequestsWriter:writer handler:^(RMTStreamingInputCallResponse *response, diff --git a/src/objective-c/tests/LocalClearTextTests.m b/src/objective-c/tests/LocalClearTextTests.m index 10c9f13ea3..4317614dd9 100644 --- a/src/objective-c/tests/LocalClearTextTests.m +++ b/src/objective-c/tests/LocalClearTextTests.m @@ -64,7 +64,7 @@ static NSString * const kService = @"RouteGuide"; // interface:kService // method:@"EmptyCall"]; // -// id<GRXWriter> requestsWriter = [GRXWriter writerWithValue:[NSData data]]; +// GRXWriter *requestsWriter = [GRXWriter writerWithValue:[NSData data]]; // // GRPCCall *call = [[GRPCCall alloc] initWithHost:kRouteGuideHost // method:method @@ -91,7 +91,7 @@ static NSString * const kService = @"RouteGuide"; service:kService method:@"RecordRoute"]; - id<GRXWriter> requestsWriter = [GRXWriter emptyWriter]; + GRXWriter *requestsWriter = [GRXWriter emptyWriter]; GRPCCall *call = [[GRPCCall alloc] initWithHost:kRouteGuideHost path:method.HTTPPath @@ -122,7 +122,7 @@ static NSString * const kService = @"RouteGuide"; RGDPoint *point = [RGDPoint message]; point.latitude = 28E7; point.longitude = -15E7; - id<GRXWriter> requestsWriter = [GRXWriter writerWithValue:[point data]]; + GRXWriter *requestsWriter = [GRXWriter writerWithValue:[point data]]; GRPCCall *call = [[GRPCCall alloc] initWithHost:kRouteGuideHost path:method.HTTPPath |