1/* 2 * 3 * Copyright 2015 gRPC authors. 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 */ 18 19#import "GRXForwardingWriter.h" 20 21@interface GRXForwardingWriter ()<GRXWriteable> 22@end 23 24@implementation GRXForwardingWriter { 25 GRXWriter *_writer; 26 id<GRXWriteable> _writeable; 27} 28 29- (instancetype)init { 30 return [self initWithWriter:nil]; 31} 32 33// Designated initializer 34- (instancetype)initWithWriter:(GRXWriter *)writer { 35 if (!writer) { 36 return nil; 37 } 38 if (writer.state != GRXWriterStateNotStarted) { 39 [NSException raise:NSInvalidArgumentException 40 format:@"The writer argument must not have already started."]; 41 } 42 if ((self = [super init])) { 43 _writer = writer; 44 } 45 return self; 46} 47 48// This is used to send a completion or an error to the writeable. It nillifies 49// our reference to it in order to guarantee no more messages are sent to it, 50// and to release it. 51- (void)finishOutputWithError:(NSError *)errorOrNil { 52 id<GRXWriteable> writeable = _writeable; 53 _writeable = nil; 54 [writeable writesFinishedWithError:errorOrNil]; 55} 56 57// This is used to stop the input writer. It nillifies our reference to it 58// to release it. 59- (void)finishInput { 60 GRXWriter *writer = _writer; 61 _writer = nil; 62 writer.state = GRXWriterStateFinished; 63} 64 65#pragma mark GRXWriteable implementation 66 67- (void)writeValue:(id)value { 68 [_writeable writeValue:value]; 69} 70 71- (void)writesFinishedWithError:(NSError *)errorOrNil { 72 _writer = nil; 73 [self finishOutputWithError:errorOrNil]; 74} 75 76#pragma mark GRXWriter implementation 77 78- (GRXWriterState)state { 79 return _writer ? _writer.state : GRXWriterStateFinished; 80} 81 82- (void)setState:(GRXWriterState)state { 83 if (state == GRXWriterStateFinished) { 84 _writeable = nil; 85 [self finishInput]; 86 } else { 87 _writer.state = state; 88 } 89} 90 91- (void)startWithWriteable:(id<GRXWriteable>)writeable { 92 _writeable = writeable; 93 [_writer startWithWriteable:self]; 94} 95 96- (void)finishWithError:(NSError *)errorOrNil { 97 [self finishOutputWithError:errorOrNil]; 98 [self finishInput]; 99} 100 101@end 102