Repository: thrift Updated Branches: refs/heads/master f9c318ca9 -> 3b61971c8
THRIFT-3041 Generate asynchronous clients for Cocoa Client: Cocoa Patch: Mike Riley <[email protected]> This closes #400 Project: http://git-wip-us.apache.org/repos/asf/thrift/repo Commit: http://git-wip-us.apache.org/repos/asf/thrift/commit/f332d164 Tree: http://git-wip-us.apache.org/repos/asf/thrift/tree/f332d164 Diff: http://git-wip-us.apache.org/repos/asf/thrift/diff/f332d164 Branch: refs/heads/master Commit: f332d16460b2d0e344a47cf43d9d8bf9953d2cdb Parents: f9c318c Author: Jens Geyer <[email protected]> Authored: Thu Apr 16 21:58:28 2015 +0200 Committer: Jens Geyer <[email protected]> Committed: Thu Apr 16 22:11:11 2015 +0200 ---------------------------------------------------------------------- compiler/cpp/src/generate/t_cocoa_generator.cc | 441 ++++++++++++++------ lib/cocoa/src/TBaseClient.h | 30 ++ lib/cocoa/src/TBaseClient.m | 46 ++ lib/cocoa/src/transport/TAsyncTransport.h | 29 ++ 4 files changed, 410 insertions(+), 136 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/thrift/blob/f332d164/compiler/cpp/src/generate/t_cocoa_generator.cc ---------------------------------------------------------------------- diff --git a/compiler/cpp/src/generate/t_cocoa_generator.cc b/compiler/cpp/src/generate/t_cocoa_generator.cc index 3cb9127..a87ef4a 100644 --- a/compiler/cpp/src/generate/t_cocoa_generator.cc +++ b/compiler/cpp/src/generate/t_cocoa_generator.cc @@ -57,6 +57,9 @@ public: iter = parsed_options.find("validate_required"); validate_required_ = (iter != parsed_options.end()); + iter = parsed_options.find("async_clients"); + async_clients_ = (iter != parsed_options.end()); + out_dir_base_ = "gen-cocoa"; } @@ -128,8 +131,17 @@ public: */ void generate_cocoa_service_protocol(std::ofstream& out, t_service* tservice); + void generate_cocoa_service_async_protocol(std::ofstream& out, t_service* tservice); + void generate_cocoa_service_client_interface(std::ofstream& out, t_service* tservice); + void generate_cocoa_service_client_async_interface(std::ofstream& out, t_service* tservice); + + void generate_cocoa_service_client_send_function_implementation(ofstream& out, t_function* tfunction); + void generate_cocoa_service_client_send_function_invocation(ofstream& out, t_function* tfunction); + void generate_cocoa_service_client_recv_function_implementation(ofstream& out, t_function* tfunction); void generate_cocoa_service_client_implementation(std::ofstream& out, t_service* tservice); + void generate_cocoa_service_client_async_implementation(std::ofstream& out, t_service* tservice); + void generate_cocoa_service_server_interface(std::ofstream& out, t_service* tservice); void generate_cocoa_service_server_implementation(std::ofstream& out, t_service* tservice); void generate_cocoa_service_helpers(t_service* tservice); @@ -185,6 +197,7 @@ public: std::string declare_field(t_field* tfield); std::string declare_property(t_field* tfield); std::string function_signature(t_function* tfunction); + std::string async_function_signature(t_function* tfunction); std::string argument_list(t_struct* tstruct); std::string type_to_enum(t_type* ttype); std::string format_string_for_type(t_type* type); @@ -212,6 +225,7 @@ private: bool log_unexpected_; bool validate_required_; + bool async_clients_; }; /** @@ -258,9 +272,15 @@ string t_cocoa_generator::cocoa_imports() { */ string t_cocoa_generator::cocoa_thrift_imports() { string result = string() + "#import \"TProtocol.h\"\n" + "#import \"TApplicationException.h\"\n" - + "#import \"TProtocolException.h\"\n" + "#import \"TProtocolUtil.h\"\n" - + "#import \"TProcessor.h\"\n" + "#import \"TObjective-C.h\"\n" - + "#import \"TBase.h\"\n" + "\n"; + + "#import \"TProtocolException.h\"\n" + + "#import \"TProtocolUtil.h\"\n" + + "#import \"TProcessor.h\"\n" + + "#import \"TObjective-C.h\"\n" + + "#import \"TBase.h\"\n" + + "#import \"TAsyncTransport.h\"\n" + + "#import \"TProtocolFactory.h\"\n" + + "#import \"TBaseClient.h\"\n" + + "\n"; // Include other Thrift includes const vector<t_program*>& includes = program_->get_includes(); @@ -1209,6 +1229,11 @@ void t_cocoa_generator::generate_service(t_service* tservice) { generate_cocoa_service_helpers(tservice); generate_cocoa_service_client_implementation(f_impl_, tservice); generate_cocoa_service_server_implementation(f_impl_, tservice); + if(async_clients_) { + generate_cocoa_service_async_protocol(f_header_, tservice); + generate_cocoa_service_client_async_interface(f_header_, tservice); + generate_cocoa_service_client_async_implementation(f_impl_, tservice); + } } /** @@ -1294,20 +1319,31 @@ void t_cocoa_generator::generate_cocoa_service_protocol(ofstream& out, t_service } /** + * Generates an asynchronous service protocol definition. + * + * @param tservice The service to generate a protocol definition for + */ +void t_cocoa_generator::generate_cocoa_service_async_protocol(ofstream& out, t_service* tservice) { + out << "@protocol " << cocoa_prefix_ << tservice->get_name() << "Async" << " <NSObject>" << endl; + + vector<t_function*> functions = tservice->get_functions(); + vector<t_function*>::iterator f_iter; + for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { + out << "- " << async_function_signature(*f_iter) << ";" << endl; + } + out << "@end" << endl << endl; +} + +/** * Generates a service client interface definition. * * @param tservice The service to generate a client interface definition for */ void t_cocoa_generator::generate_cocoa_service_client_interface(ofstream& out, t_service* tservice) { - out << "@interface " << cocoa_prefix_ << tservice->get_name() << "Client : NSObject <" + out << "@interface " << cocoa_prefix_ << tservice->get_name() << "Client : TBaseClient <" << cocoa_prefix_ << tservice->get_name() << "> "; - scope_up(out); - out << indent() << "id <TProtocol> inProtocol;" << endl; - out << indent() << "id <TProtocol> outProtocol;" << endl; - scope_down(out); - out << "- (id) initWithProtocol: (id <TProtocol>) protocol;" << endl; out << "- (id) initWithInProtocol: (id <TProtocol>) inProtocol outProtocol: (id <TProtocol>) " "outProtocol;" << endl; @@ -1315,6 +1351,25 @@ void t_cocoa_generator::generate_cocoa_service_client_interface(ofstream& out, } /** + * Generates a service client interface definition. + * + * @param tservice The service to generate a client interface definition for + */ +void t_cocoa_generator::generate_cocoa_service_client_async_interface(ofstream& out, + t_service* tservice) { + out << "@interface " << cocoa_prefix_ << tservice->get_name() << "ClientAsync : TBaseClient <" + << cocoa_prefix_ << tservice->get_name() << "Async> "; + + scope_up(out); + out << indent() << "id <TAsyncTransport> asyncTransport;" << endl; + scope_down(out); + + out << "- (id) initWithProtocolFactory: (id <TProtocolFactory>) factory " + "transport: (id <TAsyncTransport>) transport;" << endl; + out << "@end" << endl << endl; +} + +/** * Generates a service server interface definition. In other words, the TProcess implementation for *the * service definition. @@ -1338,6 +1393,141 @@ void t_cocoa_generator::generate_cocoa_service_server_interface(ofstream& out, out << "@end" << endl << endl; } +void t_cocoa_generator::generate_cocoa_service_client_send_function_implementation(ofstream& out, + t_function* tfunction) { + string funname = tfunction->get_name(); + + t_function send_function(g_type_void, + string("send_") + tfunction->get_name(), + tfunction->get_arglist()); + + string argsname = tfunction->get_name() + "_args"; + + // Open function + indent(out) << "- " << function_signature(&send_function) << endl; + scope_up(out); + + // Serialize the request + out << indent() << "[outProtocol writeMessageBeginWithName: @\"" << funname << "\"" + << (tfunction->is_oneway() ? " type: TMessageType_ONEWAY" : " type: TMessageType_CALL") + << " sequenceID: 0];" << endl; + + out << indent() << "[outProtocol writeStructBeginWithName: @\"" << argsname << "\"];" << endl; + + // write out function parameters + t_struct* arg_struct = tfunction->get_arglist(); + const vector<t_field*>& fields = arg_struct->get_members(); + vector<t_field*>::const_iterator fld_iter; + for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) { + string fieldName = (*fld_iter)->get_name(); + if (type_can_be_null((*fld_iter)->get_type())) { + out << indent() << "if (" << fieldName << " != nil)"; + scope_up(out); + } + out << indent() << "[outProtocol writeFieldBeginWithName: @\"" << fieldName + << "\"" + " type: " << type_to_enum((*fld_iter)->get_type()) + << " fieldID: " << (*fld_iter)->get_key() << "];" << endl; + + generate_serialize_field(out, *fld_iter, fieldName); + + out << indent() << "[outProtocol writeFieldEnd];" << endl; + + if (type_can_be_null((*fld_iter)->get_type())) { + indent_down(); + out << indent() << "}" << endl; + } + } + + out << indent() << "[outProtocol writeFieldStop];" << endl; + out << indent() << "[outProtocol writeStructEnd];" << endl; + out << indent() << "[outProtocol writeMessageEnd];" << endl; + scope_down(out); + out << endl; +} + +void t_cocoa_generator::generate_cocoa_service_client_recv_function_implementation(ofstream& out, + t_function* tfunction) { + t_struct noargs(program_); + t_function recv_function(tfunction->get_returntype(), + string("recv_") + tfunction->get_name(), + &noargs, + tfunction->get_xceptions()); + // Open function + indent(out) << "- " << function_signature(&recv_function) << endl; + scope_up(out); + + // TODO(mcslee): Message validation here, was the seqid etc ok? + + // check for an exception + out << indent() << "TApplicationException * x = [self checkIncomingMessageException];" << endl + << indent() << "if (x != nil)"; + scope_up(out); + out << indent() << "@throw x;" << endl; + scope_down(out); + + // FIXME - could optimize here to reduce creation of temporary objects. + string resultname = function_result_helper_struct_type(tfunction); + out << indent() << cocoa_prefix_ << resultname << " * result = [[[" << cocoa_prefix_ + << resultname << " alloc] init] autorelease_stub];" << endl; + indent(out) << "[result read: inProtocol];" << endl; + indent(out) << "[inProtocol readMessageEnd];" << endl; + + // Careful, only return _result if not a void function + if (!tfunction->get_returntype()->is_void()) { + out << indent() << "if ([result successIsSet]) {" << endl << indent() + << " return [result success];" << endl << indent() << "}" << endl; + } + + t_struct* xs = tfunction->get_xceptions(); + const std::vector<t_field*>& xceptions = xs->get_members(); + vector<t_field*>::const_iterator x_iter; + for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) { + out << indent() << "if ([result " << (*x_iter)->get_name() << "IsSet]) {" << endl + << indent() << " @throw [result " << (*x_iter)->get_name() << "];" << endl << indent() + << "}" << endl; + } + + // If you get here it's an exception, unless a void function + if (tfunction->get_returntype()->is_void()) { + indent(out) << "return;" << endl; + } else { + out << indent() << "@throw [TApplicationException exceptionWithType: " + "TApplicationException_MISSING_RESULT" << endl << indent() + << " reason: @\"" << tfunction->get_name() + << " failed: unknown result\"];" << endl; + } + + // Close function + scope_down(out); + out << endl; +} + +/** + * Generates an invocation of a given 'send_' function. + * + * @param tfunction The service to generate an implementation for + */ +void t_cocoa_generator::generate_cocoa_service_client_send_function_invocation(ofstream& out, + t_function* tfunction) { + t_struct* arg_struct = tfunction->get_arglist(); + const vector<t_field*>& fields = arg_struct->get_members(); + vector<t_field*>::const_iterator fld_iter; + indent(out) << "[self send_" << tfunction->get_name(); + bool first = true; + for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) { + string fieldName = (*fld_iter)->get_name(); + out << " "; + if (first) { + first = false; + out << ": " << fieldName; + } else { + out << fieldName << ": " << fieldName; + } + } + out << "];" << endl; +} + /** * Generates a service client implementation. * @@ -1364,160 +1554,116 @@ void t_cocoa_generator::generate_cocoa_service_client_implementation(ofstream& o scope_down(out); out << endl; - // dealloc - out << "- (void) dealloc" << endl; - scope_up(out); - out << indent() << "[inProtocol release_stub];" << endl; - out << indent() << "[outProtocol release_stub];" << endl; - out << indent() << "[super dealloc_stub];" << endl; - scope_down(out); - out << endl; - // generate client method implementations vector<t_function*> functions = tservice->get_functions(); vector<t_function*>::const_iterator f_iter; for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { - string funname = (*f_iter)->get_name(); - - t_function send_function(g_type_void, - string("send_") + (*f_iter)->get_name(), - (*f_iter)->get_arglist()); + + generate_cocoa_service_client_send_function_implementation(out, *f_iter); - string argsname = (*f_iter)->get_name() + "_args"; + if (!(*f_iter)->is_oneway()) { + generate_cocoa_service_client_recv_function_implementation(out, *f_iter); + } // Open function - indent(out) << "- " << function_signature(&send_function) << endl; + indent(out) << "- " << function_signature(*f_iter) << endl; scope_up(out); - - // Serialize the request - out << indent() << "[outProtocol writeMessageBeginWithName: @\"" << funname << "\"" - << ((*f_iter)->is_oneway() ? " type: TMessageType_ONEWAY" : " type: TMessageType_CALL") - << " sequenceID: 0];" << endl; - - out << indent() << "[outProtocol writeStructBeginWithName: @\"" << argsname << "\"];" << endl; - - // write out function parameters - t_struct* arg_struct = (*f_iter)->get_arglist(); - const vector<t_field*>& fields = arg_struct->get_members(); - vector<t_field*>::const_iterator fld_iter; - for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) { - string fieldName = (*fld_iter)->get_name(); - if (type_can_be_null((*fld_iter)->get_type())) { - out << indent() << "if (" << fieldName << " != nil)"; - scope_up(out); - } - out << indent() << "[outProtocol writeFieldBeginWithName: @\"" << fieldName - << "\"" - " type: " << type_to_enum((*fld_iter)->get_type()) - << " fieldID: " << (*fld_iter)->get_key() << "];" << endl; - - generate_serialize_field(out, *fld_iter, fieldName); - - out << indent() << "[outProtocol writeFieldEnd];" << endl; - - if (type_can_be_null((*fld_iter)->get_type())) { - scope_down(out); + generate_cocoa_service_client_send_function_invocation(out, *f_iter); + + out << indent() << "[[outProtocol transport] flush];" << endl; + if (!(*f_iter)->is_oneway()) { + out << indent(); + if (!(*f_iter)->get_returntype()->is_void()) { + out << "return "; } + out << "[self recv_" << (*f_iter)->get_name() << "];" << endl; } + scope_down(out); + out << endl; + } + indent_down(); + out << "@end" << endl << endl; +} - out << indent() << "[outProtocol writeFieldStop];" << endl; - out << indent() << "[outProtocol writeStructEnd];" << endl; +/** + * Generates a service client implementation for its asynchronous interface. + * + * @param tservice The service to generate an implementation for + */ +void t_cocoa_generator::generate_cocoa_service_client_async_implementation(ofstream& out, + t_service* tservice) { + out << "@implementation " << cocoa_prefix_ << tservice->get_name() << "ClientAsync" << endl << endl + << "- (id) initWithProtocolFactory: (id <TProtocolFactory>) factory " + "transport: (id <TAsyncTransport>) transport;" << endl; - out << indent() << "[outProtocol writeMessageEnd];" << endl << indent() - << "[[outProtocol transport] flush];" << endl; + scope_up(out); + out << indent() << "self = [super init];" << endl; + out << indent() << "inProtocol = [[factory newProtocolOnTransport:transport] retain_stub];" << endl; + out << indent() << "outProtocol = inProtocol;" << endl; + out << indent() << "asyncTransport = transport;" << endl; + out << indent() << "return self;" << endl; + scope_down(out); + out << endl; - scope_down(out); - out << endl; + // generate client method implementations + vector<t_function*> functions = tservice->get_functions(); + vector<t_function*>::const_iterator f_iter; + for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { + + generate_cocoa_service_client_send_function_implementation(out, *f_iter); if (!(*f_iter)->is_oneway()) { - t_struct noargs(program_); - t_function recv_function((*f_iter)->get_returntype(), - string("recv_") + (*f_iter)->get_name(), - &noargs, - (*f_iter)->get_xceptions()); - // Open function - indent(out) << "- " << function_signature(&recv_function) << endl; - scope_up(out); - - // TODO(mcslee): Message validation here, was the seqid etc ok? + generate_cocoa_service_client_recv_function_implementation(out, *f_iter); + } - // check for an exception - out << indent() << "int msgType = 0;" << endl << indent() - << "[inProtocol readMessageBeginReturningName: nil type: &msgType sequenceID: NULL];" - << endl << indent() << "if (msgType == TMessageType_EXCEPTION) {" << endl << indent() - << " TApplicationException * x = [TApplicationException read: inProtocol];" << endl - << indent() << " [inProtocol readMessageEnd];" << endl << indent() << " @throw x;" - << endl << indent() << "}" << endl; + // Open function + indent(out) << "- " << async_function_signature(*f_iter) << endl; + scope_up(out); + indent(out) << "@try {" << endl; + indent_up(); + generate_cocoa_service_client_send_function_invocation(out, *f_iter); + indent_down(); + out << indent() << "} @catch(TException * texception) {" << endl; + indent_up(); + out << indent() << "failureBlock(texception);" << endl + << indent() << "return;" << endl; + indent_down(); + indent(out) << "}" << endl; + + out << indent() << "[asyncTransport flush:^{" << endl; + indent_up(); - // FIXME - could optimize here to reduce creation of temporary objects. - string resultname = function_result_helper_struct_type(*f_iter); - out << indent() << cocoa_prefix_ << resultname << " * result = [[[" << cocoa_prefix_ - << resultname << " alloc] init] autorelease_stub];" << endl; - indent(out) << "[result read: inProtocol];" << endl; - indent(out) << "[inProtocol readMessageEnd];" << endl; + out << indent() << "@try {" << endl; + indent_up(); - // Careful, only return _result if not a void function - if (!(*f_iter)->get_returntype()->is_void()) { - out << indent() << "if ([result successIsSet]) {" << endl << indent() - << " return [result success];" << endl << indent() << "}" << endl; - } + string recv_invocation = "[self recv_" + (*f_iter)->get_name() + "]"; + if (!(*f_iter)->is_oneway() && (*f_iter)->get_returntype()->is_void()) { + out << indent() << recv_invocation << ";" << endl; + } + out << indent() << "responseBlock("; + if (!(*f_iter)->is_oneway() && !(*f_iter)->get_returntype()->is_void()) { + out << recv_invocation; + } + out << ");" << endl; - t_struct* xs = (*f_iter)->get_xceptions(); - const std::vector<t_field*>& xceptions = xs->get_members(); - vector<t_field*>::const_iterator x_iter; - for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) { - out << indent() << "if ([result " << (*x_iter)->get_name() << "IsSet]) {" << endl - << indent() << " @throw [result " << (*x_iter)->get_name() << "];" << endl << indent() - << "}" << endl; - } + indent_down(); - // If you get here it's an exception, unless a void function - if ((*f_iter)->get_returntype()->is_void()) { - indent(out) << "return;" << endl; - } else { - out << indent() << "@throw [TApplicationException exceptionWithType: " - "TApplicationException_MISSING_RESULT" << endl << indent() - << " reason: @\"" << (*f_iter)->get_name() - << " failed: unknown result\"];" << endl; - } + out << indent() << "} @catch(TException * texception) {" << endl; + indent_up(); - // Close function - scope_down(out); - out << endl; - } + out << indent() << "failureBlock(texception);" << endl; - // Open function - indent(out) << "- " << function_signature(*f_iter) << endl; - scope_up(out); - indent(out) << "[self send_" << funname; + indent_down(); + out << indent() << "}" << endl; - // Declare the function arguments - bool first = true; - for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) { - string fieldName = (*fld_iter)->get_name(); - out << " "; - if (first) { - first = false; - out << ": " << fieldName; - } else { - out << fieldName << ": " << fieldName; - } - } - out << "];" << endl; + indent_down(); + out << indent() << "} failure:failureBlock];" << endl; - if (!(*f_iter)->is_oneway()) { - out << indent(); - if (!(*f_iter)->get_returntype()->is_void()) { - out << "return "; - } - out << "[self recv_" << funname << "];" << endl; - } scope_down(out); + out << endl; } - indent_down(); - out << "@end" << endl << endl; } @@ -2563,6 +2709,28 @@ string t_cocoa_generator::function_signature(t_function* tfunction) { } /** + * Renders a function signature that returns asynchronously instead of + * literally returning. + * + * @param tfunction Function definition + * @return String of rendered function definition + */ +string t_cocoa_generator::async_function_signature(t_function* tfunction) { + t_type* ttype = tfunction->get_returntype(); + t_struct* targlist = tfunction->get_arglist(); + std::string response_param = "dispatch_block_t"; + if (!ttype->is_void()) { + response_param = "void (^)(" + type_name(ttype) + ")"; + } + std::string result = "(void) " + tfunction->get_name() + + argument_list(tfunction->get_arglist()) + + (targlist->get_members().size() ? " response" : "") + + ": (" + response_param + ") responseBlock " + + "failure : (TAsyncFailureBlock) failureBlock"; + return result; +} + +/** * Renders a colon separated list of types and names, suitable for an * objective-c parameter list */ @@ -2683,4 +2851,5 @@ THRIFT_REGISTER_GENERATOR( "Cocoa", " log_unexpected: Log every time an unexpected field ID or type is encountered.\n" " validate_required:\n" - " Throws exception if any required field is not set.\n") + " Throws exception if any required field is not set.\n" + " async_clients: Generate clients which invoke asynchronously via block syntax.\n") http://git-wip-us.apache.org/repos/asf/thrift/blob/f332d164/lib/cocoa/src/TBaseClient.h ---------------------------------------------------------------------- diff --git a/lib/cocoa/src/TBaseClient.h b/lib/cocoa/src/TBaseClient.h new file mode 100644 index 0000000..12944b1 --- /dev/null +++ b/lib/cocoa/src/TBaseClient.h @@ -0,0 +1,30 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#import "TProtocol.h" +#import "TApplicationException.h" + +@interface TBaseClient : NSObject { + id <TProtocol> inProtocol; + id <TProtocol> outProtocol; +} + +- (TApplicationException *)checkIncomingMessageException; + +@end http://git-wip-us.apache.org/repos/asf/thrift/blob/f332d164/lib/cocoa/src/TBaseClient.m ---------------------------------------------------------------------- diff --git a/lib/cocoa/src/TBaseClient.m b/lib/cocoa/src/TBaseClient.m new file mode 100644 index 0000000..d15f9d3 --- /dev/null +++ b/lib/cocoa/src/TBaseClient.m @@ -0,0 +1,46 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#import "TBaseClient.h" +#import "TApplicationException.h" +#import "TObjective-C.h" + +@implementation TBaseClient + +- (void) dealloc +{ + [inProtocol release_stub]; + [outProtocol release_stub]; + [super dealloc_stub]; +} + +- (TApplicationException *)checkIncomingMessageException +{ + int msgType = 0; + [inProtocol readMessageBeginReturningName: nil type: &msgType sequenceID: NULL]; + if (msgType == TMessageType_EXCEPTION) { + TApplicationException * x = [TApplicationException read: inProtocol]; + [inProtocol readMessageEnd]; + return x; + } + + return nil; +} + +@end http://git-wip-us.apache.org/repos/asf/thrift/blob/f332d164/lib/cocoa/src/transport/TAsyncTransport.h ---------------------------------------------------------------------- diff --git a/lib/cocoa/src/transport/TAsyncTransport.h b/lib/cocoa/src/transport/TAsyncTransport.h new file mode 100644 index 0000000..f75b701 --- /dev/null +++ b/lib/cocoa/src/transport/TAsyncTransport.h @@ -0,0 +1,29 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#import "TTransport.h" +#import "TException.h" + +typedef void(^TAsyncFailureBlock)(TException *); + +@protocol TAsyncTransport <TTransport> + +- (void) flush:(dispatch_block_t)flushed failure:(TAsyncFailureBlock)failure; + +@end
