Groundwork for exception support:

     Auto generate result structs that combine return type and any thrown exceptions
     Add __isset struct to all user defined and auto defined struct to mark fields that are explicilty read
     Modified client and server generation code to marshal result structs

     Added base facebook::thrift::Exception class 


git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@664751 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/compiler/src/cpp_generator.py b/compiler/src/cpp_generator.py
index 2c8efc5..92636c5 100644
--- a/compiler/src/cpp_generator.py
+++ b/compiler/src/cpp_generator.py
@@ -256,11 +256,11 @@
 CPP_TRANSPORT = CPP_TRANSPORT_NS+"::TTransport"
 CPP_TRANSPORTP = CPP_SP.substitute(klass=CPP_TRANSPORT)
 
-CPP_SERVER_FUNCTION_DECLARATION = Template("""    void process_${function}("""+CPP_TRANSPORTP+""" itrans, """+CPP_TRANSPORTP+""" otrans);
+CPP_SERVER_FUNCTION_DECLARATION = Template("""    void process_${function}(uint32_t seqid, """+CPP_TRANSPORTP+""" itrans, """+CPP_TRANSPORTP+""" otrans);
 """)
 
 CPP_SERVER_FUNCTION_DEFINITION = Template("""
-void ${service}ServerIf::process_${function}("""+CPP_TRANSPORTP+""" itrans, """+CPP_TRANSPORTP+""" otrans) {
+void ${service}ServerIf::process_${function}(uint32_t seqid, """+CPP_TRANSPORTP+""" itrans, """+CPP_TRANSPORTP+""" otrans) {
 
     uint32_t xfer = 0;
 
@@ -268,6 +268,8 @@
 
     ${argsStructReader};
 
+    iprot->readMessageEnd(itrans);
+
     ${returnValueDeclaration};
 
     ${functionCall};
@@ -276,12 +278,37 @@
 
     ${returnToResult};
 
+    oprot->writeMessageBegin(otrans, """+CPP_PROTOCOL_REPLY+""", seqid);
+
     ${resultStructWriter};
 
+    oprot->writeMessaeEnd(otrans);
+
     otrans->flush();
 }
 """)
 
+CPP_SERVER_PROCESS_DEFINITION = Template("""
+bool ${service}ServerIf::process("""+CPP_TRANSPORTP+""" itrans, """+CPP_TRANSPORTP+""" otrans) {
+
+    uint32_t xfer = 0;
+
+    std::string name;
+
+    """+CPP_MESSAGE_TYPE+""" messageType;
+
+    uint32_t seqid;
+
+    _iprot->readMessageBegin(_itrans, name, messageType, cseqid);
+
+    if(messageType == """+CPP_PROTOCOL_CALL+""") {
+${callProcessSwitch}
+    } else {
+        throw """+CPP_EXCEPTION+"""(\"Unexpected message type\");     
+    }
+}
+""")
+
 CPP_PROTOCOL_TSTOP = CPP_PROTOCOL_NS+"::T_STOP"
 CPP_PROTOCOL_TTYPE = CPP_PROTOCOL_NS+"::TType"
 CPP_PROTOCOL_MESSAGE_TYPE = CPP_PROTOCOL_NS+"::TMessageType"
@@ -452,6 +479,11 @@
 	
 	result+= toServerFunctionDefinition(service.name, function, debugp)
 
+    
+    callProcessSwitch = "if"+string.join(["(name.compare(\""+function.name+"\") == 0) {"+toServerProcessFunctionCall(function)+";}" for function in service.functionList], "\n    else if")
+
+    result+= CPP_SERVER_PROCESS_DEFINITION(service=service.name, callProcessSwitch=callProcessSwitch)
+
     return result
 
 def toServerDefinition(program, debugp=None):