Revision: 7877
Author: [email protected]
Date: Mon Apr  5 09:04:38 2010
Log: Checkpoint incomplete modifications to shared plugin code for alternate
transport support.

http://code.google.com/p/google-web-toolkit/source/detail?r=7877

Added:
 /changes/jat/csproto/plugins/common/SocketTransport.cpp
 /changes/jat/csproto/plugins/common/SocketTransport.h
 /changes/jat/csproto/plugins/common/Transport.cpp
 /changes/jat/csproto/plugins/common/Transport.h
Modified:
 /changes/jat/csproto/plugins/common/HostChannel.cpp
 /changes/jat/csproto/plugins/common/HostChannel.h
 /changes/jat/csproto/plugins/common/InvokeSpecialMessage.cpp
 /changes/jat/csproto/plugins/common/LoadJsniMessage.cpp
 /changes/jat/csproto/plugins/common/LoadModuleMessage.cpp
 /changes/jat/csproto/plugins/common/ProtocolVersionMessage.cpp
 /changes/jat/csproto/plugins/common/ReturnMessage.cpp

=======================================
--- /dev/null
+++ /changes/jat/csproto/plugins/common/SocketTransport.cpp Mon Apr 5 09:04:38 2010
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2010 Google Inc.
+ *
+ * Licensed 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 "SocketTransport.h"
+
+SocketTransport::SocketTransport(const char* host, unsigned port) {
+  sock.connect(host, port);
+}
+
+SocketTransport::~SocketTransport() {
+  sock.disconnect();
+}
+
+bool SocketTransport::endWriteMessage() {
+  if (!sock.isConnected()) {
+    return false;
+  }
+  if (!sock.flush()) {
+    return false;
+  }
+  return true;
+}
+
+bool SocketTransport::isConnected() {
+  return sock.isConnected();
+}
+
+bool SocketTransport::writeByte(const char data) {
+  if (!isConnected()) {
+    return false;
+  }
+  if (!sock.writeByte(data)) {
+    return false;
+  }
+  return true;
+}
+
+int SocketTransport::readByte() {
+  if (!isConnected()) {
+    return -1;
+  }
+  return sock.readByte();
+}
=======================================
--- /dev/null
+++ /changes/jat/csproto/plugins/common/SocketTransport.h Mon Apr 5 09:04:38 2010
@@ -0,0 +1,46 @@
+#ifndef __H_SocketTransport
+#define __H_SocketTransport
+/*
+ * Copyright 2010 Google Inc.
+ *
+ * Licensed 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 "Transport.h"
+#include "Socket.h"
+
+/**
+ * Transports via TCP/IP socket.
+ */
+class SocketTransport : public Transport {
+  Socket sock;
+public:
+  SocketTransport(const char* host, unsigned port);
+
+  virtual ~SocketTransport();
+
+  // flush any output buffer and terminate a message to send
+  virtual bool endWriteMessage();
+
+  // return true if this transport is connected (not all transports may be
+  // able to detect disconnection)
+  virtual bool isConnected();
+
+  // read a single unsigned byte from the transport, -1 on error
+  virtual int readByte();
+
+  // write a single byte to the transport, return true on success
+  virtual bool writeByte(char c);
+};
+
+#endif
=======================================
--- /dev/null
+++ /changes/jat/csproto/plugins/common/Transport.cpp Mon Apr 5 09:04:38 2010
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2010 Google Inc.
+ *
+ * Licensed 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 "Transport.h"
+
+Transport::~Transport() {
+}
+
+// many of these will be overridden in subclasses
+bool Transport::beginReadMessage() {
+  return true;
+}
+
+virtual void Transport::endReadMessage() {
+}
+
+virtual bool Transport::beginWriteMessage() {
+  return true;
+}
+
+virtual bool Transport::endWriteMessage() {
+  return true;
+}
+
+virtual bool Transport::isConnected() {
+  return true;
+}
+
+// FailTransport
+virtual bool FailTransport::beginReadMessage() {
+  return false;
+}
+
+virtual bool FailTransport::beginWriteMessage() {
+  return false;
+}
+
+virtual bool FailTransport::endWriteMessage() {
+  return false:
+}
+
+virtual bool FailTransport::isConnected() {
+  return false;
+}
+
+virtual int FailTransport::readByte() {
+  return -1;
+}
+
+virtual bool FailTransport::writeByte(char c) {
+  return false;
+}
=======================================
--- /dev/null
+++ /changes/jat/csproto/plugins/common/Transport.h     Mon Apr  5 09:04:38 2010
@@ -0,0 +1,62 @@
+#ifndef __H_Transport
+#define __H_Transport
+/*
+ * Copyright 2010 Google Inc.
+ *
+ * Licensed 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.
+ */
+
+/**
+ * Abstract class for transports.
+ */
+class Transport {
+public:
+  virtual ~Transport();
+
+  // start reading a message, return true on success
+  virtual bool beginReadMessage();
+
+  // mark that a complete message has been read
+  virtual void endReadMessage();
+
+  // start a message being sent, return true on success
+  virtual bool beginWriteMessage();
+
+ // flush any output buffer and terminate a message to send, true on success
+  virtual bool endWriteMessage();
+
+  // return true if this transport is connected (not all transports may be
+  // able to detect disconnection)
+  virtual bool isConnected();
+
+  // read a single unsigned byte from the transport, -1 on error
+  virtual int readByte() = 0;
+
+  // write a single byte to the transport, return true on success
+  virtual bool writeByte(char c) = 0;
+};
+
+/**
+ * A transport that fails everything.
+ */
+class FailTransport : public Transport {
+public:
+  virtual bool beginReadMessage();
+  virtual bool beginWriteMessage();
+  virtual bool endWriteMessage();
+  virtual bool isConnected();
+  virtual int readByte();
+  virtual bool writeByte(char c);
+};
+
+#endif
=======================================
--- /changes/jat/csproto/plugins/common/HostChannel.cpp Mon Nov 23 13:18:40 2009 +++ /changes/jat/csproto/plugins/common/HostChannel.cpp Mon Apr 5 09:04:38 2010
@@ -20,20 +20,12 @@
 #include <cerrno>

 #include "Debug.h"
-
-#ifdef _WINDOWS
-#include <winsock2.h>
-#include <ws2tcpip.h>
-#else
-#include <netdb.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
 #include <unistd.h>
 #include <sys/time.h>
-#endif
 #include <time.h>

+#include "SocketTransport.h"
+
 #include "Platform.h"
 #include "ByteOrder.h"

@@ -63,7 +55,17 @@
   Debug::log(Debug::Info)
       << "Initiating GWT Development Mode connection to host " << host
       << ", port " << port << Debug::flush;
-  return sock.connect(host, port);
+  socketTransport = new SocketTransport(host, port);
+  if (!socketTransport->isConnected()) {
+    delete socketTransport;
+    socketTransport = 0;
+    return false;
+  }
+  if (transport) {
+    delete transport;
+  }
+  transport = socketTransport;
+  return true;
 }

 bool HostChannel::init(SessionHandler* handler, int minProtoVers,
@@ -75,9 +77,8 @@
       << Debug::flush;
   // TODO(jat): support transport selection
CheckVersionsMessage::send(*this, minProtoVers, maxProtoVers, hostedHtmlVers);
-  flush();
   char type;
-  if (!readByte(type)) {
+  if (!readMessageType(&type)) {
     handler->fatalError(*this, "Failed to receive message type");
Debug::log(Debug::Error) << "Failed to receive message type" << Debug::flush;
     disconnectFromHost();
@@ -108,10 +109,22 @@
       return false;
     }
     default:
+      endReadMessage();
       return false;
   }
   return true;
 }
+
+void HostChannel::disconnectTransport() {
+  if (socketTransport && socketTransport != transport) {
+    delete socketTransport;
+    socketTransport = 0;
+  }
+  if (transport) {
+    delete transport;
+    transport = 0;
+  }
+}

 bool HostChannel::disconnectFromHost() {
   Debug::log(Debug::Debugging) << "Disconnecting channel" << Debug::flush;
@@ -119,9 +132,10 @@
Debug::log(Debug::Error) << "Disconnecting already disconnected channel" << Debug::flush;
     return false;
   }
+  beginWriteMessage();
   QuitMessage::send(*this);
-  flush();
-  sock.disconnect();
+  endWriteMessage();
+  disconnectTransport();
   return true;
 }

@@ -236,10 +250,9 @@
ReturnMessage* HostChannel::reactToMessages(SessionHandler* handler, bool expectReturn) {
   char type;
   while (true) {
-    flush();
     Debug::log(Debug::Spam) << "Waiting for response, flushed output"
         << Debug::flush;
-    if (!readByte(type)) {
+    if (!readMessageType(&type)) {
       if (isConnected()) {
         Debug::log(Debug::Error) << "Failed to receive message type"
             << Debug::flush;
@@ -310,6 +323,7 @@
          disconnectFromHost();
         return 0;
       default:
+        endReadMessage();
         // TODO(jat): error handling
         Debug::log(Debug::Error) << "Unexpected message type " << type
             << ", expectReturn=" << expectReturn << Debug::flush;
=======================================
--- /changes/jat/csproto/plugins/common/HostChannel.h Mon Nov 23 13:18:40 2009 +++ /changes/jat/csproto/plugins/common/HostChannel.h Mon Apr 5 09:04:38 2010
@@ -23,7 +23,7 @@
 #include <string>

 #include "ByteOrder.h"
-#include "Socket.h"
+#include "SocketTransport.h"
 #include "Platform.h"
 #include "Message.h"
 #include "ReturnMessage.h"
@@ -31,15 +31,25 @@
 #include "SessionHandler.h"

 class HostChannel {
-  Socket sock;
+  Transport* transport;
+  SocketTransport* socketTransport;
   static ByteOrder byteOrder;
   SessionHandler* handler;

 public:
+  HostChannel() {
+    transport = new FailTransport();
+  }
+
   ~HostChannel() {
     if (isConnected()) {
       disconnectFromHost();
     }
+    if (socketTransport != transport) {
+      delete socketTransport;
+    }
+    socketTransport = 0;
+    delete transport;
Debug::log(Debug::Debugging) << "HostChannel destroyed" << Debug::flush;
   }

@@ -53,7 +63,7 @@
   bool disconnectFromHost();

   bool isConnected() const {
-    return sock.isConnected();
+    return transport->isConnected() && socketTransport->isConnected();
   }

   bool readBytes(void* data, size_t dataLen) {
@@ -94,12 +104,39 @@
   bool readDouble(double& doubleRef);
   bool sendDouble(const double data);

+  bool beginReadMessage() {
+    return transport->beginReadMessage();
+  }
+
+  void endReadMessage() {
+    transport->endReadMessage();
+  }
+
+  bool beginWriteMessage() {
+    return transport->beginReadMessage();
+  }
+
+  bool endWriteMessage() {
+    return transport->endWriteMessage();
+  }
+
+  /**
+ * Reads the message type tag, starting reading a new message. Caller must
+   * call endReadMessage() when the complete message has been received.
+   *
+   * @param data output parameter
+   */
+  bool readMessageType(char* data) {
+    beginReadMessage();
+    return readByte(*data);
+  }
+
   bool readByte(char& data) {
     if (!isConnected()) {
       handler->disconnectDetected();
       return false;
     }
-    int c = sock.readByte();
+    int c = transport->readByte();
     if (c < 0) {
       handler->disconnectDetected();
       return false;
@@ -109,14 +146,10 @@
   }

   bool sendByte(const char data) {
-    if (!isConnected()) {
+    if (!transport->writeByte(data)) {
       handler->disconnectDetected();
       return false;
     }
-    if (!sock.writeByte(data)) {
-      handler->disconnectDetected();
-      return false;
-    }
     return true;
   }

@@ -139,21 +172,12 @@
   bool reactToMessages(SessionHandler* handler) {
     return !reactToMessages(handler, false);
   }
-
-  bool flush() {
-    if (!sock.isConnected()) {
-      handler->disconnectDetected();
-      return false;
-    }
-    if (!sock.flush()) {
-      handler->disconnectDetected();
-      return false;
-    }
-    return true;
-  }

ReturnMessage* reactToMessagesWhileWaitingForReturn(SessionHandler* handler) {
     return reactToMessages(handler, true);
   }
+
+private:
+  void disconnectTransport();
 };
 #endif
=======================================
--- /changes/jat/csproto/plugins/common/InvokeSpecialMessage.cpp Mon Aug 3 08:30:11 2009 +++ /changes/jat/csproto/plugins/common/InvokeSpecialMessage.cpp Mon Apr 5 09:04:38 2010
@@ -1,12 +1,12 @@
 /*
  * Copyright 2008 Google Inc.
- *
+ *
* Licensed 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
@@ -34,29 +34,18 @@
  */
 InvokeSpecialMessage* InvokeSpecialMessage::receive(HostChannel& channel) {
   char dispatchId;
-  if (!channel.readByte(dispatchId)) {
-    // TODO(jat): error handling
-    printf("Failed to read method name\n");
-    return 0;
-  }
-  int numArgs;
-  if (!channel.readInt(numArgs)) {
-    // TODO(jat): error handling
-    printf("Failed to read #args\n");
-    return 0;
-  }
+  int numArgs = 0;
+  bool success = channel.readByte(dispatchId)
+      && channel.readInt(numArgs);
   scoped_array<Value> args(new Value[numArgs]);
   for (int i = 0; i < numArgs; ++i) {
-    if (!channel.readValue(args[i])) {
-      // TODO(jat): error handling
-      printf("Failed to read arg[%d]\n", i);
-      return 0;
-    }
-  }
-
+    success &= channel.readValue(args[i]);
+  }
+
   SessionHandler::SpecialMethodId id =
     static_cast<SessionHandler::SpecialMethodId>(dispatchId);
-  return new InvokeSpecialMessage(id, numArgs, args.release());
+  channel.endReadMessage();
+ return success ? new InvokeSpecialMessage(id, numArgs, args.release()) : 0;
 }

 /**
@@ -64,11 +53,13 @@
  */
 bool InvokeSpecialMessage::send(HostChannel& channel, int dispatchId,
     int numArgs, const Value* args) {
-  if (!channel.sendByte(TYPE)) return false;
-  if (!channel.sendByte(dispatchId)) return false;
-  if (!channel.sendInt(numArgs)) return false;
-  for (int i = 0; i < numArgs; ++i) {
-    if (!channel.sendValue(args[i])) return false;
-  }
-  return true;
-}
+  bool success = channel.beginWriteMessage()
+      && channel.sendByte(TYPE)
+      && channel.sendByte(dispatchId)
+      && channel.sendInt(numArgs);
+  for (int i = 0; success && i < numArgs; ++i) {
+    success = channel.sendValue(args[i]);
+  }
+  if (!channel.endWriteMessage()) return false;
+  return success;
+}
=======================================
--- /changes/jat/csproto/plugins/common/LoadJsniMessage.cpp Mon Aug 3 08:30:11 2009 +++ /changes/jat/csproto/plugins/common/LoadJsniMessage.cpp Mon Apr 5 09:04:38 2010
@@ -1,12 +1,12 @@
 /*
  * Copyright 2008 Google Inc.
- *
+ *
* Licensed 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
@@ -18,9 +18,8 @@

 LoadJsniMessage* LoadJsniMessage::receive(HostChannel& channel) {
   std::string js;
-  if (!channel.readString(js)) {
-    // TODO(jat): error handling
-    return 0;
-  }
-  return new LoadJsniMessage(js);
-}
+  bool success = channel.readString(js);
+  channel.endReadMessage();
+  // TODO(jat): error handling
+  return success ? new LoadJsniMessage(js) : 0;
+}
=======================================
--- /changes/jat/csproto/plugins/common/LoadModuleMessage.cpp Sat Aug 22 16:59:24 2009 +++ /changes/jat/csproto/plugins/common/LoadModuleMessage.cpp Mon Apr 5 09:04:38 2010
@@ -33,13 +33,16 @@
   Debug::log(Debug::Spam) << "LoadModule(url=\"" << url << "\", tabKey=\""
       << "\", sessionKey=\"" << sessionKey << "\", module=\"" << moduleName
       << "\")" << Debug::flush;
+  if (!channel.beginWriteMessage()) return false;
   if (!channel.sendByte(TYPE) || !channel.sendString(url)
       || !channel.sendString(tabKey)
       || !channel.sendString(sessionKey)
       || !channel.sendString(moduleName)
       || !channel.sendString(userAgent)) {
+    channel.endWriteMessage();
     return false;
   }
+  if (!channel.endWriteMessage()) return false;
scoped_ptr<ReturnMessage> ret(channel.reactToMessagesWhileWaitingForReturn(
       handler));
   if (!ret.get()) {
=======================================
--- /changes/jat/csproto/plugins/common/ProtocolVersionMessage.cpp Mon Aug 24 10:08:49 2009 +++ /changes/jat/csproto/plugins/common/ProtocolVersionMessage.cpp Mon Apr 5 09:04:38 2010
@@ -35,6 +35,7 @@
     printf("Failed to read version\n");
     return 0;
   }
+  channel.endReadMessage();
   return new ProtocolVersionMessage(version);
 }

@@ -42,7 +43,9 @@
  * Send a ProtocolVersion message on the channel.
  */
 bool ProtocolVersionMessage::send(HostChannel& channel, int version) {
-  if (!channel.sendByte(TYPE)) return false;
-  if (!channel.sendInt(version)) return false;
-  return true;
-}
+  if (!channel.beginWriteMessage()) return false;
+  bool success = channel.sendByte(TYPE)
+      && channel.sendInt(version);
+  if (!channel.endWriteMessage()) return false;
+  return success;
+}
=======================================
--- /changes/jat/csproto/plugins/common/ReturnMessage.cpp Mon Aug 3 08:30:11 2009 +++ /changes/jat/csproto/plugins/common/ReturnMessage.cpp Mon Apr 5 09:04:38 2010
@@ -1,12 +1,12 @@
 /*
  * Copyright 2008 Google Inc.
- *
+ *
* Licensed 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
@@ -20,7 +20,7 @@
 char ReturnMessage::getType() const {
   return TYPE;
 }
-
+
 ReturnMessage* ReturnMessage::receive(HostChannel& channel) {
   char isException;
   if (!channel.readByte(isException)) {
@@ -32,11 +32,15 @@
     // TODO(jat): error handling
     return 0;
   }
+  channel.endReadMessage();
   return new ReturnMessage(isException != 0, retval);
 }

bool ReturnMessage::send(HostChannel& channel, bool isException, const Value& retval) {
-  if (!channel.sendByte(TYPE)) return false;
-  if (!channel.sendByte(isException ? 1 : 0)) return false;
-  return channel.sendValue(retval);
-}
+  if (!channel.beginWriteMessage()) return false;
+  bool success = channel.sendByte(TYPE)
+      && channel.sendByte(isException ? 1 : 0)
+      && channel.sendValue(retval);
+  if (!channel.endWriteMessage()) return false;
+  return success;
+}

--
http://groups.google.com/group/Google-Web-Toolkit-Contributors

To unsubscribe, reply using "remove me" as the subject.

Reply via email to