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.