#ifndef CHROME_TEST_CHROMEDRIVER_NET_SYNC_WEBSOCKET_IMPL_H_
#define CHROME_TEST_CHROMEDRIVER_NET_SYNC_WEBSOCKET_IMPL_H_
#include <list>
#include <string>
#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/synchronization/condition_variable.h"
#include "base/synchronization/lock.h"
#include "chrome/test/chromedriver/net/sync_websocket.h"
#include "chrome/test/chromedriver/net/websocket.h"
#include "net/base/completion_callback.h"
#include "net/socket_stream/socket_stream.h"
namespace base {
class WaitableEvent;
}
namespace net {
class URLRequestContextGetter;
}
class GURL;
class SyncWebSocketImpl : public SyncWebSocket {
public:
explicit SyncWebSocketImpl(net::URLRequestContextGetter* context_getter);
virtual ~SyncWebSocketImpl();
virtual bool IsConnected() OVERRIDE;
virtual bool Connect(const GURL& url) OVERRIDE;
virtual bool Send(const std::string& message) OVERRIDE;
virtual StatusCode ReceiveNextMessage(
std::string* message,
const base::TimeDelta& timeout) OVERRIDE;
virtual bool HasNextMessage() OVERRIDE;
private:
struct CoreTraits;
class Core : public WebSocketListener,
public base::RefCountedThreadSafe<Core, CoreTraits> {
public:
explicit Core(net::URLRequestContextGetter* context_getter);
bool IsConnected();
bool Connect(const GURL& url);
bool Send(const std::string& message);
SyncWebSocket::StatusCode ReceiveNextMessage(
std::string* message,
const base::TimeDelta& timeout);
bool HasNextMessage();
virtual void OnMessageReceived(const std::string& message) OVERRIDE;
virtual void OnClose() OVERRIDE;
private:
friend class base::RefCountedThreadSafe<Core, CoreTraits>;
friend class base::DeleteHelper<Core>;
friend struct CoreTraits;
virtual ~Core();
void ConnectOnIO(const GURL& url,
bool* success,
base::WaitableEvent* event);
void OnConnectCompletedOnIO(bool* connected,
base::WaitableEvent* event,
int error);
void SendOnIO(const std::string& message,
bool* result,
base::WaitableEvent* event);
void OnDestruct() const;
scoped_refptr<net::URLRequestContextGetter> context_getter_;
scoped_ptr<WebSocket> socket_;
base::Lock lock_;
bool is_connected_;
std::list<std::string> received_queue_;
base::ConditionVariable on_update_event_;
};
scoped_refptr<Core> core_;
};
struct SyncWebSocketImpl::CoreTraits {
static void Destruct(const SyncWebSocketImpl::Core* core) {
core->OnDestruct();
}
};
#endif