Initial checkin of OOPHM plugins into trunk. Testing of non-XPCOM plugins
is still required, and more platforms need to be built.
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@5868 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/plugins/common/Socket.h b/plugins/common/Socket.h
new file mode 100644
index 0000000..90298f6
--- /dev/null
+++ b/plugins/common/Socket.h
@@ -0,0 +1,170 @@
+#ifndef _H_Socket
+#define _H_Socket
+/*
+ * 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
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+#include "Platform.h"
+#include "Debug.h"
+
+#include <string>
+
+#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
+
+/**
+ * Encapsulates platform dependencies regarding buffered sockets.
+ */
+class Socket {
+private:
+ // Buffer size, chosen to fit in a single packet after TCP/IP overhead.
+ static const int BUF_SIZE = 1400;
+
+ // Can't rely on a sentinel value for the socket descriptor
+ bool connected;
+
+ SOCKETTYPE sock;
+
+ // Read buffer
+ char* readBuf;
+
+ // One bye past end of valid data in readBuf
+ char* readValid;
+
+ // Current read pointer
+ char* readBufPtr;
+
+ // Write buffer
+ char* writeBuf;
+
+ // Current write pointer
+ char* writeBufPtr;
+
+ // Stats
+ unsigned long numReads;
+ unsigned long long totReadBytes;
+ size_t maxReadBytes;
+
+ unsigned long numWrites;
+ unsigned long long totWriteBytes;
+ size_t maxWriteBytes;
+
+private:
+ void init();
+ bool fillReadBuf();
+ bool emptyWriteBuf();
+
+public:
+ Socket() : connected(false), readBuf(new char[BUF_SIZE]), writeBuf(new char[BUF_SIZE]) {
+ readBufPtr = readValid = readBuf;
+ writeBufPtr = writeBuf;
+ numReads = numWrites = 0;
+ maxReadBytes = maxWriteBytes = 0;
+ totReadBytes = totWriteBytes = 0;
+ init();
+ }
+
+ ~Socket() {
+ disconnect();
+#ifdef _WINDOWS
+ if (0) WSACleanup();
+#endif
+ // TODO(jat): LEAK LEAK LEAK
+ // delete[] readBuf;
+ // delete[] writeBuf;
+ Debug::log(Debug::Debugging) << "Socket: #r=" << numReads << ", bytes/read="
+ << (numReads ? totReadBytes / numReads : 0) << ", maxr=" << maxReadBytes << "; #w="
+ << numWrites << ", bytes/write=" << (numWrites ? totWriteBytes / numWrites : 0) << ", maxw="
+ << maxWriteBytes << Debug::flush;
+ }
+
+ /**
+ * Connects this socket to a specified port on a host.
+ *
+ * @param host host name or IP address to connect to
+ * @param port TCP port to connect to
+ * @return true if the connection succeeds
+ */
+ bool connect(const char* host, int port);
+
+ /**
+ * Returns true if the socket is connected.
+ */
+ bool isConnected() const {
+ return connected;
+ }
+
+ /**
+ * Disconnect this socket.
+ *
+ * @param doFlush true (the default value) if the socket should be flushed.
+ * @return true if disconnect succeeds
+ */
+ bool disconnect(bool doFlush = true);
+
+ /**
+ * Read a single byte from the socket.
+ *
+ * @return -1 on error, otherwise unsigned byte read.
+ */
+ int readByte() {
+ if (readBufPtr >= readValid) {
+ if (!fillReadBuf()) {
+ return -1;
+ }
+ }
+ return static_cast<unsigned char>(*readBufPtr++);
+ }
+
+ /**
+ * Write a single byte to the socket.
+ *
+ * @return true on success.
+ */
+ bool writeByte(char c) {
+ if (writeBufPtr >= writeBuf + BUF_SIZE) {
+ if (!emptyWriteBuf()) {
+ return false;
+ }
+ }
+ *writeBufPtr++ = c;
+ return true;
+ }
+
+ /**
+ * Flush any pending writes on the socket.
+ *
+ * @return true on success
+ */
+ bool flush() {
+ if (writeBufPtr > writeBuf) {
+ if (!emptyWriteBuf()) {
+ return false;
+ }
+ }
+ return true;
+ }
+};
+
+#endif