cpp: Eliminate circular dependency between thrift libraries

Previously, Thrift.cpp contained TApplicationException, which was using
TProtocol methods, defined in TProtocol.h.  This caused a circular
dependency since libprotocol depends on Thrift.h.  This change moves
TApplicationException into its own file.

git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@920682 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/lib/cpp/src/TApplicationException.cpp b/lib/cpp/src/TApplicationException.cpp
new file mode 100644
index 0000000..32238fb
--- /dev/null
+++ b/lib/cpp/src/TApplicationException.cpp
@@ -0,0 +1,80 @@
+/*
+ * 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.
+ */
+
+#include <TApplicationException.h>
+#include <protocol/TProtocol.h>
+
+namespace apache { namespace thrift {
+
+uint32_t TApplicationException::read(apache::thrift::protocol::TProtocol* iprot) {
+  uint32_t xfer = 0;
+  std::string fname;
+  apache::thrift::protocol::TType ftype;
+  int16_t fid;
+
+  xfer += iprot->readStructBegin(fname);
+
+  while (true) {
+    xfer += iprot->readFieldBegin(fname, ftype, fid);
+    if (ftype == apache::thrift::protocol::T_STOP) {
+      break;
+    }
+    switch (fid) {
+    case 1:
+      if (ftype == apache::thrift::protocol::T_STRING) {
+        xfer += iprot->readString(message_);
+      } else {
+        xfer += iprot->skip(ftype);
+      }
+      break;
+    case 2:
+      if (ftype == apache::thrift::protocol::T_I32) {
+        int32_t type;
+        xfer += iprot->readI32(type);
+        type_ = (TApplicationExceptionType)type;
+      } else {
+        xfer += iprot->skip(ftype);
+      }
+      break;
+    default:
+      xfer += iprot->skip(ftype);
+      break;
+    }
+    xfer += iprot->readFieldEnd();
+  }
+
+  xfer += iprot->readStructEnd();
+  return xfer;
+}
+
+uint32_t TApplicationException::write(apache::thrift::protocol::TProtocol* oprot) const {
+  uint32_t xfer = 0;
+  xfer += oprot->writeStructBegin("TApplicationException");
+  xfer += oprot->writeFieldBegin("message", apache::thrift::protocol::T_STRING, 1);
+  xfer += oprot->writeString(message_);
+  xfer += oprot->writeFieldEnd();
+  xfer += oprot->writeFieldBegin("type", apache::thrift::protocol::T_I32, 2);
+  xfer += oprot->writeI32(type_);
+  xfer += oprot->writeFieldEnd();
+  xfer += oprot->writeFieldStop();
+  xfer += oprot->writeStructEnd();
+  return xfer;
+}
+
+}} // apache::thrift
diff --git a/lib/cpp/src/TApplicationException.h b/lib/cpp/src/TApplicationException.h
new file mode 100644
index 0000000..e125c52
--- /dev/null
+++ b/lib/cpp/src/TApplicationException.h
@@ -0,0 +1,105 @@
+/*
+ * 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.
+ */
+
+#ifndef _THRIFT_TAPPLICATIONEXCEPTION_H_
+#define _THRIFT_TAPPLICATIONEXCEPTION_H_ 1
+
+#include <Thrift.h>
+
+
+namespace apache { namespace thrift {
+
+namespace protocol {
+  class TProtocol;
+}
+
+class TApplicationException : public TException {
+ public:
+
+  /**
+   * Error codes for the various types of exceptions.
+   */
+  enum TApplicationExceptionType {
+    UNKNOWN = 0,
+    UNKNOWN_METHOD = 1,
+    INVALID_MESSAGE_TYPE = 2,
+    WRONG_METHOD_NAME = 3,
+    BAD_SEQUENCE_ID = 4,
+    MISSING_RESULT = 5
+  };
+
+  TApplicationException() :
+    TException(),
+    type_(UNKNOWN) {}
+
+  TApplicationException(TApplicationExceptionType type) :
+    TException(),
+    type_(type) {}
+
+  TApplicationException(const std::string& message) :
+    TException(message),
+    type_(UNKNOWN) {}
+
+  TApplicationException(TApplicationExceptionType type,
+                        const std::string& message) :
+    TException(message),
+    type_(type) {}
+
+  virtual ~TApplicationException() throw() {}
+
+  /**
+   * Returns an error code that provides information about the type of error
+   * that has occurred.
+   *
+   * @return Error code
+   */
+  TApplicationExceptionType getType() {
+    return type_;
+  }
+
+  virtual const char* what() const throw() {
+    if (message_.empty()) {
+      switch (type_) {
+        case UNKNOWN              : return "TApplicationException: Unknown application exception";
+        case UNKNOWN_METHOD       : return "TApplicationException: Unknown method";
+        case INVALID_MESSAGE_TYPE : return "TApplicationException: Invalid message type";
+        case WRONG_METHOD_NAME    : return "TApplicationException: Wrong method name";
+        case BAD_SEQUENCE_ID      : return "TApplicationException: Bad sequence identifier";
+        case MISSING_RESULT       : return "TApplicationException: Missing result";
+        default                   : return "TApplicationException: (Invalid exception type)";
+      };
+    } else {
+      return message_.c_str();
+    }
+  }
+
+  uint32_t read(protocol::TProtocol* iprot);
+  uint32_t write(protocol::TProtocol* oprot) const;
+
+ protected:
+  /**
+   * Error code
+   */
+  TApplicationExceptionType type_;
+
+};
+
+}} // apache::thrift
+
+#endif // #ifndef _THRIFT_TAPPLICATIONEXCEPTION_H_
diff --git a/lib/cpp/src/Thrift.cpp b/lib/cpp/src/Thrift.cpp
index ed99205..cc0a01b 100644
--- a/lib/cpp/src/Thrift.cpp
+++ b/lib/cpp/src/Thrift.cpp
@@ -20,7 +20,6 @@
 #include <Thrift.h>
 #include <cstring>
 #include <boost/lexical_cast.hpp>
-#include <protocol/TProtocol.h>
 #include <stdarg.h>
 #include <stdio.h>
 
@@ -90,59 +89,4 @@
 #endif  // HAVE_STRERROR_R
 }
 
-uint32_t TApplicationException::read(apache::thrift::protocol::TProtocol* iprot) {
-  uint32_t xfer = 0;
-  std::string fname;
-  apache::thrift::protocol::TType ftype;
-  int16_t fid;
-
-  xfer += iprot->readStructBegin(fname);
-
-  while (true) {
-    xfer += iprot->readFieldBegin(fname, ftype, fid);
-    if (ftype == apache::thrift::protocol::T_STOP) {
-      break;
-    }
-    switch (fid) {
-    case 1:
-      if (ftype == apache::thrift::protocol::T_STRING) {
-        xfer += iprot->readString(message_);
-      } else {
-        xfer += iprot->skip(ftype);
-      }
-      break;
-    case 2:
-      if (ftype == apache::thrift::protocol::T_I32) {
-        int32_t type;
-        xfer += iprot->readI32(type);
-        type_ = (TApplicationExceptionType)type;
-      } else {
-        xfer += iprot->skip(ftype);
-      }
-      break;
-    default:
-      xfer += iprot->skip(ftype);
-      break;
-    }
-    xfer += iprot->readFieldEnd();
-  }
-
-  xfer += iprot->readStructEnd();
-  return xfer;
-}
-
-uint32_t TApplicationException::write(apache::thrift::protocol::TProtocol* oprot) const {
-  uint32_t xfer = 0;
-  xfer += oprot->writeStructBegin("TApplicationException");
-  xfer += oprot->writeFieldBegin("message", apache::thrift::protocol::T_STRING, 1);
-  xfer += oprot->writeString(message_);
-  xfer += oprot->writeFieldEnd();
-  xfer += oprot->writeFieldBegin("type", apache::thrift::protocol::T_I32, 2);
-  xfer += oprot->writeI32(type_);
-  xfer += oprot->writeFieldEnd();
-  xfer += oprot->writeFieldStop();
-  xfer += oprot->writeStructEnd();
-  return xfer;
-}
-
 }} // apache::thrift
diff --git a/lib/cpp/src/Thrift.h b/lib/cpp/src/Thrift.h
index 27a6476..1bce23f 100644
--- a/lib/cpp/src/Thrift.h
+++ b/lib/cpp/src/Thrift.h
@@ -82,10 +82,6 @@
 
 extern TOutput GlobalOutput;
 
-namespace protocol {
-  class TProtocol;
-}
-
 class TException : public std::exception {
  public:
   TException() {}
@@ -108,77 +104,6 @@
 
 };
 
-class TApplicationException : public TException {
- public:
-
-  /**
-   * Error codes for the various types of exceptions.
-   */
-  enum TApplicationExceptionType
-  { UNKNOWN = 0
-  , UNKNOWN_METHOD = 1
-  , INVALID_MESSAGE_TYPE = 2
-  , WRONG_METHOD_NAME = 3
-  , BAD_SEQUENCE_ID = 4
-  , MISSING_RESULT = 5
-  };
-
-  TApplicationException() :
-    TException(),
-    type_(UNKNOWN) {}
-
-  TApplicationException(TApplicationExceptionType type) :
-    TException(),
-    type_(type) {}
-
-  TApplicationException(const std::string& message) :
-    TException(message),
-    type_(UNKNOWN) {}
-
-  TApplicationException(TApplicationExceptionType type,
-                        const std::string& message) :
-    TException(message),
-    type_(type) {}
-
-  virtual ~TApplicationException() throw() {}
-
-  /**
-   * Returns an error code that provides information about the type of error
-   * that has occurred.
-   *
-   * @return Error code
-   */
-  TApplicationExceptionType getType() {
-    return type_;
-  }
-
-  virtual const char* what() const throw() {
-    if (message_.empty()) {
-      switch (type_) {
-        case UNKNOWN              : return "TApplicationException: Unknown application exception";
-        case UNKNOWN_METHOD       : return "TApplicationException: Unknown method";
-        case INVALID_MESSAGE_TYPE : return "TApplicationException: Invalid message type";
-        case WRONG_METHOD_NAME    : return "TApplicationException: Wrong method name";
-        case BAD_SEQUENCE_ID      : return "TApplicationException: Bad sequence identifier";
-        case MISSING_RESULT       : return "TApplicationException: Missing result";
-        default                   : return "TApplicationException: (Invalid exception type)";
-      };
-    } else {
-      return message_.c_str();
-    }
-  }
-
-  uint32_t read(protocol::TProtocol* iprot);
-  uint32_t write(protocol::TProtocol* oprot) const;
-
- protected:
-  /**
-   * Error code
-   */
-  TApplicationExceptionType type_;
-
-};
-
 
 // Forward declare this structure used by TDenseProtocol
 namespace reflection { namespace local {
diff --git a/lib/cpp/src/protocol/TDenseProtocol.cpp b/lib/cpp/src/protocol/TDenseProtocol.cpp
index 8e76dc4..b9a3d1f 100644
--- a/lib/cpp/src/protocol/TDenseProtocol.cpp
+++ b/lib/cpp/src/protocol/TDenseProtocol.cpp
@@ -266,7 +266,7 @@
 uint32_t TDenseProtocol::writeMessageBegin(const std::string& name,
                                            const TMessageType messageType,
                                            const int32_t seqid) {
-  throw TApplicationException("TDenseProtocol doesn't work with messages (yet).");
+  throw TException("TDenseProtocol doesn't work with messages (yet).");
 
   int32_t version = (VERSION_2) | ((int32_t)messageType);
   uint32_t wsize = 0;
@@ -290,7 +290,7 @@
 
     if (type_spec_ == NULL) {
       resetState();
-      throw TApplicationException("TDenseProtocol: No type specified.");
+      throw TException("TDenseProtocol: No type specified.");
     } else {
       assert(type_spec_->ttype == T_STRUCT);
       ts_stack_.push_back(type_spec_);
@@ -481,7 +481,7 @@
 uint32_t TDenseProtocol::readMessageBegin(std::string& name,
                                           TMessageType& messageType,
                                           int32_t& seqid) {
-  throw TApplicationException("TDenseProtocol doesn't work with messages (yet).");
+  throw TException("TDenseProtocol doesn't work with messages (yet).");
 
   uint32_t xfer = 0;
   int32_t sz;
@@ -514,7 +514,7 @@
 
     if (type_spec_ == NULL) {
       resetState();
-      throw TApplicationException("TDenseProtocol: No type specified.");
+      throw TException("TDenseProtocol: No type specified.");
     } else {
       assert(type_spec_->ttype == T_STRUCT);
       ts_stack_.push_back(type_spec_);