summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/test/ui/ppapi_uitest.cc1
-rw-r--r--ppapi/api/dev/ppb_websocket_dev.idl99
-rw-r--r--ppapi/c/dev/ppb_websocket_dev.h101
-rw-r--r--ppapi/cpp/completion_callback.h2
-rw-r--r--ppapi/cpp/dev/websocket_dev.cc148
-rw-r--r--ppapi/cpp/dev/websocket_dev.h164
-rw-r--r--ppapi/ppapi_sources.gypi2
-rw-r--r--ppapi/tests/test_websocket.cc62
-rw-r--r--ppapi/tests/test_websocket.h2
9 files changed, 432 insertions, 149 deletions
diff --git a/chrome/test/ui/ppapi_uitest.cc b/chrome/test/ui/ppapi_uitest.cc
index 02a2f2e..60e8490 100644
--- a/chrome/test/ui/ppapi_uitest.cc
+++ b/chrome/test/ui/ppapi_uitest.cc
@@ -597,6 +597,7 @@ TEST_PPAPI_IN_PROCESS_WITH_WS(WebSocket_InvalidClose)
TEST_PPAPI_IN_PROCESS_WITH_WS(WebSocket_ValidClose)
TEST_PPAPI_IN_PROCESS_WITH_WS(WebSocket_GetProtocol)
TEST_PPAPI_IN_PROCESS_WITH_WS(WebSocket_TextSendReceive)
+TEST_PPAPI_IN_PROCESS_WITH_WS(WebSocket_CcInterfaces)
TEST_PPAPI_IN_PROCESS(AudioConfig_ValidConfigs)
TEST_PPAPI_IN_PROCESS(AudioConfig_InvalidConfigs)
diff --git a/ppapi/api/dev/ppb_websocket_dev.idl b/ppapi/api/dev/ppb_websocket_dev.idl
index 6dd0bd8..cd31296 100644
--- a/ppapi/api/dev/ppb_websocket_dev.idl
+++ b/ppapi/api/dev/ppb_websocket_dev.idl
@@ -110,14 +110,22 @@ interface PPB_WebSocket_Dev {
* <code>protocols</code>.
*
* @param[in] callback A <code>PP_CompletionCallback</code> which is called
- * when the connection is established or an error occurs in establishing
+ * when a connection is established or an error occurs in establishing
* connection.
*
- * @return In case of immediate failure, returns an error code as follows.
- * Returns <code>PP_ERROR_BADARGUMENT</code> corresponding to JavaScript
- * SyntaxError and <code>PP_ERROR_NOACCESS</code> corresponding to JavaScript
- * SecurityError. Otherwise, returns <code>PP_OK_COMPLETIONPENDING</code>
- * and invokes <code>callback</code> later.
+ * @return An int32_t containing an error code from <code>pp_errors.h</code>.
+ * Returns <code>PP_ERROR_BADARGUMENT</code> if specified <code>url</code>,
+ * or <code>protocols</code> contains invalid string as
+ * <code>The WebSocket API specification</code> defines. It corresponds to
+ * SyntaxError of the specification.
+ * Returns <code>PP_ERROR_NOACCESS</code> if the protocol specified in the
+ * <code>url</code> is not a secure protocol, but the origin of the caller
+ * has a secure scheme. Also returns it if the port specified in the
+ * <code>url</code> is a port to which the user agent is configured to block
+ * access because the port is a well-known port like SMTP. It corresponds to
+ * SecurityError of the specification.
+ * Returns <code>PP_ERROR_INPROGRESS</code> if the call is not the first
+ * time.
*/
int32_t Connect([in] PP_Resource web_socket,
[in] PP_Var url,
@@ -140,14 +148,17 @@ interface PPB_WebSocket_Dev {
* <code>PP_VARTYPE_STRING</code>.
*
* @param[in] callback A <code>PP_CompletionCallback</code> which is called
- * when the connection is closed or an error occurs in closing connection.
- *
- * @return In case of immediate failure, returns an error code as follows.
- * Returns <code>PP_ERROR_BADARGUMENT</code> corresponding to JavaScript
- * SyntaxError and <code>PP_ERROR_NOACCESS</code> corresponding to JavaScript
- * InvalidAccessError. Otherwise, returns
- * <code>PP_OK_COMPLETIONPENDING</code> and invokes <code>callback</code>
- * later.
+ * when the connection is closed or an error occurs in closing the
+ * connection.
+ *
+ * @return An int32_t containing an error code from <code>pp_errors.h</code>.
+ * Returns <code>PP_ERROR_BADARGUMENT</code> if <code>reason</code> contains
+ * an invalid character as a UTF-8 string, or longer than 123 bytes. It
+ * corresponds to JavaScript SyntaxError of the specification.
+ * Returns <code>PP_ERROR_NOACCESS</code> if the code is not an integer
+ * equal to 1000 or in the range 3000 to 4999. It corresponds to
+ * InvalidAccessError of the specification. Returns
+ * <code>PP_ERROR_INPROGRESS</code> if the call is not the first time.
*/
int32_t Close([in] PP_Resource web_socket,
[in] uint16_t code,
@@ -156,27 +167,26 @@ interface PPB_WebSocket_Dev {
/**
* ReceiveMessage() receives a message from the WebSocket server.
- * This interface only returns bytes of a single message. That is, this
- * interface must be called at least N times to receive N messages, no matter
- * how small each message is.
+ * This interface only returns a single message. That is, this interface must
+ * be called at least N times to receive N messages, no matter how small each
+ * message is.
*
* @param[in] web_socket A <code>PP_Resource</code> corresponding to a
* WebSocket.
*
* @param[out] message The received message is copied to provided
- * <code>message</code>.
+ * <code>message</code>. The <code>message</code> must remain valid until
+ * the ReceiveMessage operation completes.
*
* @param[in] callback A <code>PP_CompletionCallback</code> which is called
- * when the receiving message is completed. It is ignored when the function
- * return <code>PP_OK</code>.
- *
- * @return In case of immediate failure, returns
- * <code>PP_ERROR_FAILED</code>. If a message is currently available, returns
- * <code>PP_OK</code>. Otherwise, returns <PP_OK_COMPLETIONPENDING</code>
- * and invokes <code>callback</code> later. At that case, if GetReadyState()
- * returns <code>PP_WEBSOCKETREADYSTATE_OPEN</code>, the received
- * message is also copied to procided <code>message</code>. Otherwise,
- * the connection is closed and ReceiveMessage() failed to receive a message.
+ * when the receiving message is completed. It is ignored if ReceiveMessage
+ * completes synchronously and returns <code>PP_OK</code>.
+ *
+ * @return An int32_t containing an error code from <code>pp_errors.h</code>.
+ * If an error is detected or connection is closed, returns
+ * <code>PP_ERROR_FAILED</code> after all buffered messages are received.
+ * Until buffered message become empty, continues to returns
+ * <code>PP_OK</code> as if connection is still established without errors.
*/
int32_t ReceiveMessage([in] PP_Resource web_socket,
[out] PP_Var message,
@@ -192,12 +202,15 @@ interface PPB_WebSocket_Dev {
* buffer. So caller can free <code>message</code> safely after returning
* from the function.
*
- * @return In case of immediate failure, returns an error code as follows.
- * Returns <code>PP_ERROR_FAILED</code> corresponding to JavaScript
- * InvalidStateError and <code>PP_ERROR_BADARGUMENT</code> corresponding to
- * JavaScript SyntaxError. Otherwise, return <code>PP_OK</code>.
- * <code>PP_OK</code> doesn't necessarily mean that the server received the
- * message.
+ * @return An int32_t containing an error code from <code>pp_errors.h</code>.
+ * Returns <code>PP_ERROR_FAILED</code> if the ReadyState is
+ * <code>PP_WEBSOCKETREADYSTATE_CONNECTING_DEV</code>. It corresponds
+ * JavaScript InvalidStateError of the specification.
+ * Returns <code>PP_ERROR_BADARGUMENT</code> if provided <code>message</code>
+ * of string type contains an invalid character as a UTF-8 string. It
+ * corresponds to JavaScript SyntaxError of the specification.
+ * Otherwise, returns <code>PP_OK</code>, but it doesn't necessarily mean
+ * that the server received the message.
*/
int32_t SendMessage([in] PP_Resource web_socket,
[in] PP_Var message);
@@ -207,10 +220,6 @@ interface PPB_WebSocket_Dev {
* messages that have been queued for the WebSocket connection to send but
* have not been transmitted to the network yet.
*
- * Note: This interface might not be able to return exact bytes in the first
- * release. Current WebSocket implementation can not estimate exact protocol
- * frame overheads.
- *
* @param[in] web_socket A <code>PP_Resource</code> corresponding to a
* WebSocket.
*
@@ -236,8 +245,8 @@ interface PPB_WebSocket_Dev {
* @param[in] web_socket A <code>PP_Resource</code> corresponding to a
* WebSocket.
*
- * @return Returns a <code>PP_VARTYPE_STRING</code> var. if called before the
- * close reason is set, its data is empty string. Returns a
+ * @return Returns a <code>PP_VARTYPE_STRING</code> var. If called before the
+ * close reason is set, it contains an empty string. Returns a
* <code>PP_VARTYPE_UNDEFINED</code> if called on an invalid resource.
*/
PP_Var GetCloseReason([in] PP_Resource web_socket);
@@ -252,7 +261,7 @@ interface PPB_WebSocket_Dev {
* @return Returns <code>PP_FALSE</code> if called before the connection is
* closed, or called on an invalid resource. Otherwise, returns
* <code>PP_TRUE</code> if the connection was closed cleanly, or returns
- * <code>PP_FALSE</code> if the connection was closed by abnormal reasons.
+ * <code>PP_FALSE</code> if the connection was closed for abnormal reasons.
*/
PP_Bool GetCloseWasClean([in] PP_Resource web_socket);
@@ -264,9 +273,9 @@ interface PPB_WebSocket_Dev {
* WebSocket.
*
* @return Returns a <code>PP_VARTYPE_STRING</code> var. If called before the
- * connection is established, its data is empty string. Returns a
+ * connection is established, its data is an empty string. Returns a
* <code>PP_VARTYPE_UNDEFINED</code> if called on an invalid resource.
- * Currently its data for valid resources are always empty string.
+ * Currently its data for valid resources are always an empty string.
*/
PP_Var GetExtensions([in] PP_Resource web_socket);
@@ -278,7 +287,7 @@ interface PPB_WebSocket_Dev {
* WebSocket.
*
* @return Returns a <code>PP_VARTYPE_STRING</code> var. If called before the
- * connection is established, its data is empty string. Returns a
+ * connection is established, it contains the empty string. Returns a
* <code>PP_VARTYPE_UNDEFINED</code> if called on an invalid resource.
*/
PP_Var GetProtocol([in] PP_Resource web_socket);
@@ -302,7 +311,7 @@ interface PPB_WebSocket_Dev {
* WebSocket.
*
* @return Returns a <code>PP_VARTYPE_STRING</code> var. If called before the
- * connection is established, its data is empty string. Return a
+ * connection is established, it contains the empty string. Return a
* <code>PP_VARTYPE_UNDEFINED</code> if called on an invalid resource.
*/
PP_Var GetURL([in] PP_Resource web_socket);
diff --git a/ppapi/c/dev/ppb_websocket_dev.h b/ppapi/c/dev/ppb_websocket_dev.h
index 0e54db1..34bad3b 100644
--- a/ppapi/c/dev/ppb_websocket_dev.h
+++ b/ppapi/c/dev/ppb_websocket_dev.h
@@ -3,7 +3,7 @@
* found in the LICENSE file.
*/
-/* From dev/ppb_websocket_dev.idl modified Wed Nov 16 02:46:08 2011. */
+/* From dev/ppb_websocket_dev.idl modified Fri Dec 16 14:25:06 2011. */
#ifndef PPAPI_C_DEV_PPB_WEBSOCKET_DEV_H_
#define PPAPI_C_DEV_PPB_WEBSOCKET_DEV_H_
@@ -128,14 +128,22 @@ struct PPB_WebSocket_Dev {
* <code>protocols</code>.
*
* @param[in] callback A <code>PP_CompletionCallback</code> which is called
- * when the connection is established or an error occurs in establishing
+ * when a connection is established or an error occurs in establishing
* connection.
*
- * @return In case of immediate failure, returns an error code as follows.
- * Returns <code>PP_ERROR_BADARGUMENT</code> corresponding to JavaScript
- * SyntaxError and <code>PP_ERROR_NOACCESS</code> corresponding to JavaScript
- * SecurityError. Otherwise, returns <code>PP_OK_COMPLETIONPENDING</code>
- * and invokes <code>callback</code> later.
+ * @return An int32_t containing an error code from <code>pp_errors.h</code>.
+ * Returns <code>PP_ERROR_BADARGUMENT</code> if specified <code>url</code>,
+ * or <code>protocols</code> contains invalid string as
+ * <code>The WebSocket API specification</code> defines. It corresponds to
+ * SyntaxError of the specification.
+ * Returns <code>PP_ERROR_NOACCESS</code> if the protocol specified in the
+ * <code>url</code> is not a secure protocol, but the origin of the caller
+ * has a secure scheme. Also returns it if the port specified in the
+ * <code>url</code> is a port to which the user agent is configured to block
+ * access because the port is a well-known port like SMTP. It corresponds to
+ * SecurityError of the specification.
+ * Returns <code>PP_ERROR_INPROGRESS</code> if the call is not the first
+ * time.
*/
int32_t (*Connect)(PP_Resource web_socket,
struct PP_Var url,
@@ -157,14 +165,17 @@ struct PPB_WebSocket_Dev {
* <code>PP_VARTYPE_STRING</code>.
*
* @param[in] callback A <code>PP_CompletionCallback</code> which is called
- * when the connection is closed or an error occurs in closing connection.
- *
- * @return In case of immediate failure, returns an error code as follows.
- * Returns <code>PP_ERROR_BADARGUMENT</code> corresponding to JavaScript
- * SyntaxError and <code>PP_ERROR_NOACCESS</code> corresponding to JavaScript
- * InvalidAccessError. Otherwise, returns
- * <code>PP_OK_COMPLETIONPENDING</code> and invokes <code>callback</code>
- * later.
+ * when the connection is closed or an error occurs in closing the
+ * connection.
+ *
+ * @return An int32_t containing an error code from <code>pp_errors.h</code>.
+ * Returns <code>PP_ERROR_BADARGUMENT</code> if <code>reason</code> contains
+ * an invalid character as a UTF-8 string, or longer than 123 bytes. It
+ * corresponds to JavaScript SyntaxError of the specification.
+ * Returns <code>PP_ERROR_NOACCESS</code> if the code is not an integer
+ * equal to 1000 or in the range 3000 to 4999. It corresponds to
+ * InvalidAccessError of the specification. Returns
+ * <code>PP_ERROR_INPROGRESS</code> if the call is not the first time.
*/
int32_t (*Close)(PP_Resource web_socket,
uint16_t code,
@@ -172,27 +183,26 @@ struct PPB_WebSocket_Dev {
struct PP_CompletionCallback callback);
/**
* ReceiveMessage() receives a message from the WebSocket server.
- * This interface only returns bytes of a single message. That is, this
- * interface must be called at least N times to receive N messages, no matter
- * how small each message is.
+ * This interface only returns a single message. That is, this interface must
+ * be called at least N times to receive N messages, no matter how small each
+ * message is.
*
* @param[in] web_socket A <code>PP_Resource</code> corresponding to a
* WebSocket.
*
* @param[out] message The received message is copied to provided
- * <code>message</code>.
+ * <code>message</code>. The <code>message</code> must remain valid until
+ * the ReceiveMessage operation completes.
*
* @param[in] callback A <code>PP_CompletionCallback</code> which is called
- * when the receiving message is completed. It is ignored when the function
- * return <code>PP_OK</code>.
- *
- * @return In case of immediate failure, returns
- * <code>PP_ERROR_FAILED</code>. If a message is currently available, returns
- * <code>PP_OK</code>. Otherwise, returns <PP_OK_COMPLETIONPENDING</code>
- * and invokes <code>callback</code> later. At that case, if GetReadyState()
- * returns <code>PP_WEBSOCKETREADYSTATE_OPEN</code>, the received
- * message is also copied to procided <code>message</code>. Otherwise,
- * the connection is closed and ReceiveMessage() failed to receive a message.
+ * when the receiving message is completed. It is ignored if ReceiveMessage
+ * completes synchronously and returns <code>PP_OK</code>.
+ *
+ * @return An int32_t containing an error code from <code>pp_errors.h</code>.
+ * If an error is detected or connection is closed, returns
+ * <code>PP_ERROR_FAILED</code> after all buffered messages are received.
+ * Until buffered message become empty, continues to returns
+ * <code>PP_OK</code> as if connection is still established without errors.
*/
int32_t (*ReceiveMessage)(PP_Resource web_socket,
struct PP_Var* message,
@@ -207,12 +217,15 @@ struct PPB_WebSocket_Dev {
* buffer. So caller can free <code>message</code> safely after returning
* from the function.
*
- * @return In case of immediate failure, returns an error code as follows.
- * Returns <code>PP_ERROR_FAILED</code> corresponding to JavaScript
- * InvalidStateError and <code>PP_ERROR_BADARGUMENT</code> corresponding to
- * JavaScript SyntaxError. Otherwise, return <code>PP_OK</code>.
- * <code>PP_OK</code> doesn't necessarily mean that the server received the
- * message.
+ * @return An int32_t containing an error code from <code>pp_errors.h</code>.
+ * Returns <code>PP_ERROR_FAILED</code> if the ReadyState is
+ * <code>PP_WEBSOCKETREADYSTATE_CONNECTING_DEV</code>. It corresponds
+ * JavaScript InvalidStateError of the specification.
+ * Returns <code>PP_ERROR_BADARGUMENT</code> if provided <code>message</code>
+ * of string type contains an invalid character as a UTF-8 string. It
+ * corresponds to JavaScript SyntaxError of the specification.
+ * Otherwise, returns <code>PP_OK</code>, but it doesn't necessarily mean
+ * that the server received the message.
*/
int32_t (*SendMessage)(PP_Resource web_socket, struct PP_Var message);
/**
@@ -220,10 +233,6 @@ struct PPB_WebSocket_Dev {
* messages that have been queued for the WebSocket connection to send but
* have not been transmitted to the network yet.
*
- * Note: This interface might not be able to return exact bytes in the first
- * release. Current WebSocket implementation can not estimate exact protocol
- * frame overheads.
- *
* @param[in] web_socket A <code>PP_Resource</code> corresponding to a
* WebSocket.
*
@@ -247,8 +256,8 @@ struct PPB_WebSocket_Dev {
* @param[in] web_socket A <code>PP_Resource</code> corresponding to a
* WebSocket.
*
- * @return Returns a <code>PP_VARTYPE_STRING</code> var. if called before the
- * close reason is set, its data is empty string. Returns a
+ * @return Returns a <code>PP_VARTYPE_STRING</code> var. If called before the
+ * close reason is set, it contains an empty string. Returns a
* <code>PP_VARTYPE_UNDEFINED</code> if called on an invalid resource.
*/
struct PP_Var (*GetCloseReason)(PP_Resource web_socket);
@@ -262,7 +271,7 @@ struct PPB_WebSocket_Dev {
* @return Returns <code>PP_FALSE</code> if called before the connection is
* closed, or called on an invalid resource. Otherwise, returns
* <code>PP_TRUE</code> if the connection was closed cleanly, or returns
- * <code>PP_FALSE</code> if the connection was closed by abnormal reasons.
+ * <code>PP_FALSE</code> if the connection was closed for abnormal reasons.
*/
PP_Bool (*GetCloseWasClean)(PP_Resource web_socket);
/**
@@ -273,9 +282,9 @@ struct PPB_WebSocket_Dev {
* WebSocket.
*
* @return Returns a <code>PP_VARTYPE_STRING</code> var. If called before the
- * connection is established, its data is empty string. Returns a
+ * connection is established, its data is an empty string. Returns a
* <code>PP_VARTYPE_UNDEFINED</code> if called on an invalid resource.
- * Currently its data for valid resources are always empty string.
+ * Currently its data for valid resources are always an empty string.
*/
struct PP_Var (*GetExtensions)(PP_Resource web_socket);
/**
@@ -286,7 +295,7 @@ struct PPB_WebSocket_Dev {
* WebSocket.
*
* @return Returns a <code>PP_VARTYPE_STRING</code> var. If called before the
- * connection is established, its data is empty string. Returns a
+ * connection is established, it contains the empty string. Returns a
* <code>PP_VARTYPE_UNDEFINED</code> if called on an invalid resource.
*/
struct PP_Var (*GetProtocol)(PP_Resource web_socket);
@@ -308,7 +317,7 @@ struct PPB_WebSocket_Dev {
* WebSocket.
*
* @return Returns a <code>PP_VARTYPE_STRING</code> var. If called before the
- * connection is established, its data is empty string. Return a
+ * connection is established, it contains the empty string. Return a
* <code>PP_VARTYPE_UNDEFINED</code> if called on an invalid resource.
*/
struct PP_Var (*GetURL)(PP_Resource web_socket);
diff --git a/ppapi/cpp/completion_callback.h b/ppapi/cpp/completion_callback.h
index e83616e..2e5f38b 100644
--- a/ppapi/cpp/completion_callback.h
+++ b/ppapi/cpp/completion_callback.h
@@ -179,6 +179,8 @@ CompletionCallback BlockUntilComplete();
///
/// class MyHandler {
/// public:
+/// // If an compiler warns on following using |this| in the initializer
+/// // list, use PP_ALLOW_THIS_IN_INITIALIZER_LIST macro.
/// MyHandler() : factory_(this), offset_(0) {
/// }
///
diff --git a/ppapi/cpp/dev/websocket_dev.cc b/ppapi/cpp/dev/websocket_dev.cc
new file mode 100644
index 0000000..52ffdba
--- /dev/null
+++ b/ppapi/cpp/dev/websocket_dev.cc
@@ -0,0 +1,148 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/cpp/dev/websocket_dev.h"
+
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/c/pp_macros.h"
+#include "ppapi/cpp/completion_callback.h"
+#include "ppapi/cpp/instance.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/module_impl.h"
+#include "ppapi/cpp/var.h"
+
+namespace pp {
+
+namespace {
+
+template <> const char* interface_name<PPB_WebSocket_Dev>() {
+ return PPB_WEBSOCKET_DEV_INTERFACE;
+}
+
+} // namespace
+
+WebSocket_Dev::WebSocket_Dev(Instance* instance) {
+ if (!has_interface<PPB_WebSocket_Dev>())
+ return;
+ PassRefFromConstructor(get_interface<PPB_WebSocket_Dev>()->Create(
+ instance->pp_instance()));
+}
+
+WebSocket_Dev::~WebSocket_Dev() {
+}
+
+int32_t WebSocket_Dev::Connect(const Var& url, const Var protocols[],
+ uint32_t protocol_count, const CompletionCallback& callback) {
+ if (!has_interface<PPB_WebSocket_Dev>())
+ return PP_ERROR_BADRESOURCE;
+
+ // Convert protocols to C interface.
+ PP_Var *c_protocols = NULL;
+ if (protocol_count) {
+ c_protocols = new PP_Var[protocol_count];
+ if (!c_protocols)
+ return PP_ERROR_NOMEMORY;
+ }
+ for (uint32_t i = 0; i < protocol_count; ++i)
+ c_protocols[i] = protocols[i].pp_var();
+
+ int32_t result = get_interface<PPB_WebSocket_Dev>()->Connect(
+ pp_resource(), url.pp_var(), c_protocols, protocol_count,
+ callback.pp_completion_callback());
+ if (c_protocols)
+ delete[] c_protocols;
+ return result;
+}
+
+int32_t WebSocket_Dev::Close(uint16_t code, const Var& reason,
+ const CompletionCallback& callback) {
+ if (!has_interface<PPB_WebSocket_Dev>())
+ return PP_ERROR_BADRESOURCE;
+
+ return get_interface<PPB_WebSocket_Dev>()->Close(
+ pp_resource(), code, reason.pp_var(),
+ callback.pp_completion_callback());
+}
+
+int32_t WebSocket_Dev::ReceiveMessage(Var* message,
+ const CompletionCallback& callback) {
+ if (!has_interface<PPB_WebSocket_Dev>())
+ return PP_ERROR_BADRESOURCE;
+
+ return get_interface<PPB_WebSocket_Dev>()->ReceiveMessage(
+ pp_resource(), const_cast<PP_Var*>(&message->pp_var()),
+ callback.pp_completion_callback());
+}
+
+int32_t WebSocket_Dev::SendMessage(const Var& message) {
+ if (!has_interface<PPB_WebSocket_Dev>())
+ return PP_ERROR_BADRESOURCE;
+
+ return get_interface<PPB_WebSocket_Dev>()->SendMessage(
+ pp_resource(), message.pp_var());
+}
+
+uint64_t WebSocket_Dev::GetBufferedAmount() {
+ if (!has_interface<PPB_WebSocket_Dev>())
+ return 0;
+
+ return get_interface<PPB_WebSocket_Dev>()->GetBufferedAmount(pp_resource());
+}
+
+uint16_t WebSocket_Dev::GetCloseCode() {
+ if (!has_interface<PPB_WebSocket_Dev>())
+ return 0;
+
+ return get_interface<PPB_WebSocket_Dev>()->GetCloseCode(pp_resource());
+}
+
+Var WebSocket_Dev::GetCloseReason() {
+ if (!has_interface<PPB_WebSocket_Dev>())
+ return 0;
+
+ return Var(Var::PassRef(),
+ get_interface<PPB_WebSocket_Dev>()->GetCloseReason(pp_resource()));
+}
+
+bool WebSocket_Dev::GetCloseWasClean() {
+ if (!has_interface<PPB_WebSocket_Dev>())
+ return false;
+
+ PP_Bool result =
+ get_interface<PPB_WebSocket_Dev>()->GetCloseWasClean(pp_resource());
+ return PP_ToBool(result);
+}
+
+Var WebSocket_Dev::GetExtensions() {
+ if (!has_interface<PPB_WebSocket_Dev>())
+ return Var();
+
+ return Var(Var::PassRef(),
+ get_interface<PPB_WebSocket_Dev>()->GetExtensions(pp_resource()));
+}
+
+Var WebSocket_Dev::GetProtocol() {
+ if (!has_interface<PPB_WebSocket_Dev>())
+ return Var();
+
+ return Var(Var::PassRef(),
+ get_interface<PPB_WebSocket_Dev>()->GetProtocol(pp_resource()));
+}
+
+PP_WebSocketReadyState_Dev WebSocket_Dev::GetReadyState() {
+ if (!has_interface<PPB_WebSocket_Dev>())
+ return PP_WEBSOCKETREADYSTATE_INVALID_DEV;
+
+ return get_interface<PPB_WebSocket_Dev>()->GetReadyState(pp_resource());
+}
+
+Var WebSocket_Dev::GetURL() {
+ if (!has_interface<PPB_WebSocket_Dev>())
+ return Var();
+
+ return Var(Var::PassRef(),
+ get_interface<PPB_WebSocket_Dev>()->GetURL(pp_resource()));
+}
+
+} // namespace pp
diff --git a/ppapi/cpp/dev/websocket_dev.h b/ppapi/cpp/dev/websocket_dev.h
index 8b25b8e..42981f6 100644
--- a/ppapi/cpp/dev/websocket_dev.h
+++ b/ppapi/cpp/dev/websocket_dev.h
@@ -6,20 +6,22 @@
#define PPAPI_CPP_DEV_WEBSOCKET_DEV_H_
#include "ppapi/c/dev/ppb_websocket_dev.h"
+#include "ppapi/cpp/resource.h"
/// @file
/// This file defines the WebSocket_Dev interface.
namespace pp {
+class CompletionCallback;
+class Instance;
class Var;
/// The <code>WebSocket_Dev</code> class
-/// A version that use virtual functions
class WebSocket_Dev : public Resource {
public:
/// Constructs a WebSocket_Dev object.
- WebSocket_Dev();
+ WebSocket_Dev(Instance* instance);
/// Destructs a WebSocket_Dev object.
virtual ~WebSocket_Dev();
@@ -27,40 +29,77 @@ class WebSocket_Dev : public Resource {
/// Connect() connects to the specified WebSocket server. Caller can call
/// this method at most once.
///
- /// @param[in] url A <code>PP_Var</code> representing a WebSocket server URL.
- /// The <code>PP_VarType</code> must be <code>PP_VARTYPE_STRING</code>.
- /// @param[in] protocols A pointer to an array of <code>PP_Var</code>
- /// specifying sub-protocols. Each <code>PP_Var</code> represents one
- /// sub-protocol and its <code>PP_VarType</code> must be
- /// <code>PP_VARTYPE_STRING</code>. This argument can be null only if
+ /// @param[in] url A <code>Var</code> of string type representing a WebSocket
+ /// server URL.
+ /// @param[in] protocols A pointer to an array of string type
+ /// <code>Var</code> specifying sub-protocols. Each <code>Var</code>
+ /// represents one sub-protocol. This argument can be null only if
/// <code>protocol_count</code> is 0.
/// @param[in] protocol_count The number of sub-protocols in
/// <code>protocols</code>.
+ /// @param[in] callback A <code>CompletionCallback</code> which is called
+ /// when a connection is established or an error occurs in establishing
+ /// connection.
///
- /// @return In case of immediate failure, returns an error code as follows.
- /// Returns <code>PP_ERROR_BADARGUMENT</code> corresponding to JavaScript
- /// SyntaxError and <code>PP_ERROR_NOACCESS</code> corresponding to
- /// JavaScript SecurityError. Otherwise, returns
- /// <code>PP_OK_COMPLETIONPENDING</code> and later invokes
- /// <code>OnOpen()</code> on success or <code>OnClose()</code> on failure.
+ /// @return An int32_t containing an error code from
+ /// <code>pp_errors.h</code>.
+ /// Returns <code>PP_ERROR_BADARGUMENT</code> if specified <code>url</code>,
+ /// or <code>protocols</code> contains invalid string as
+ /// <code>The WebSocket API specification</code> defines. It corresponds to
+ /// SyntaxError of the specification.
+ /// Returns <code>PP_ERROR_NOACCESS</code> if the protocol specified in the
+ /// <code>url</code> is not a secure protocol, but the origin of the caller
+ /// has a secure scheme. Also returns it if the port specified in the
+ /// <code>url</code> is a port to which the user agent is configured to block
+ /// access because the port is a well-known port like SMTP. It corresponds to
+ /// SecurityError of the specification.
+ /// Returns <code>PP_ERROR_INPROGRESS</code> if the call is not the first
+ /// time.
int32_t Connect(const Var& url, const Var protocols[],
- uint32_t protocol_count);
+ uint32_t protocol_count, const CompletionCallback& callback);
/// Close() closes the specified WebSocket connection by specifying
/// <code>code</code> and <code>reason</code>.
///
/// @param[in] code The WebSocket close code. Ignored if it is 0.
- /// @param[in] reason A <code>PP_Var</code> which represents the WebSocket
- /// close reason. Ignored if it is <code>PP_VARTYPE_UNDEFINED</code>.
- /// Otherwise, its <code>PP_VarType</code> must be
- /// <code>PP_VARTYPE_STRING</code>.
- ///
- /// @return In case of immediate failure, returns an error code as follows.
- /// Returns <code>PP_ERROR_BADARGUMENT</code> corresponding to JavaScript
- /// SyntaxError and <code>PP_ERROR_NOACCESS</code> corresponding to
- /// JavaScript InvalidAccessError. Otherwise, returns
- /// <code>PP_OK_COMPLETIONPENDING</code> and invokes <code>OnClose</code>.
- int32_t Close(uint16_t code, const Var& reason);
+ /// @param[in] reason A <code>Var</code> of string type which represents the
+ /// WebSocket close reason. Ignored if it is undefined type.
+ /// @param[in] callback A <code>CompletionCallback</code> which is called
+ /// when the connection is closed or an error occurs in closing the
+ /// connection.
+ ///
+ /// @return An int32_t containing an error code from
+ /// <code>pp_errors.h</code>.
+ /// Returns <code>PP_ERROR_BADARGUMENT</code> if <code>reason</code> contains
+ /// an invalid character as a UTF-8 string, or longer than 123 bytes. It
+ /// corresponds to JavaScript SyntaxError of the specification.
+ /// Returns <code>PP_ERROR_NOACCESS</code> if the code is not an integer
+ /// equal to 1000 or in the range 3000 to 4999. It corresponds to
+ /// InvalidAccessError of the specification. Returns
+ /// <code>PP_ERROR_INPROGRESS</code> if the call is not the first time.
+ int32_t Close(uint16_t code, const Var& reason,
+ const CompletionCallback& callback);
+
+ /// ReceiveMessage() receives a message from the WebSocket server.
+ /// This interface only returns a single message. That is, this interface
+ /// must be called at least N times to receive N messages, no matter how
+ /// small each message is.
+ ///
+ /// @param[out] message The received message is copied to provided
+ /// <code>message</code>. The <code>message</code> must remain valid until
+ /// the ReceiveMessage operation completes.
+ /// @param[in] callback A <code>CompletionCallback</code> which is called
+ /// when the receiving message is completed. It is ignored if ReceiveMessage
+ /// completes synchronously and returns <code>PP_OK</code>.
+ ///
+ /// @return An int32_t containing an error code from
+ /// <code>pp_errors.h</code>.
+ /// If an error is detected or connection is closed, returns
+ /// <code>PP_ERROR_FAILED</code> after all buffered messages are received.
+ /// Until buffered message become empty, continues to returns
+ /// <code>PP_OK</code> as if connection is still established without errors.
+ int32_t ReceiveMessage(Var* message,
+ const CompletionCallback& callback);
/// Send() sends a message to the WebSocket server.
///
@@ -68,38 +107,61 @@ class WebSocket_Dev : public Resource {
/// buffer. So caller can free <code>data</code> safely after returning
/// from the function.
///
- /// @return In case of immediate failure, returns an error code as follows.
- /// Returns <code>PP_ERROR_FAILED</code> corresponding to JavaScript
- /// InvalidStateError and <code>PP_ERROR_BADARGUMENT</code> corresponding to
- /// JavaScript SyntaxError. Otherwise, return <code>PP_OK</code>.
- /// <code>PP_OK</code> doesn't necessarily mean that the server received the
- /// message.
- int32_t Send(const Var& data);
+ /// @return An int32_t containing an error code from
+ /// <code>pp_errors.h</code>.
+ /// Returns <code>PP_ERROR_FAILED</code> if the ReadyState is
+ /// <code>PP_WEBSOCKETREADYSTATE_CONNECTING_DEV</code>. It corresponds
+ /// JavaScript InvalidStateError of the specification.
+ /// Returns <code>PP_ERROR_BADARGUMENT</code> if provided
+ /// <code>message</code> of string type contains an invalid character as a
+ /// UTF-8 string. It corresponds to JavaScript SyntaxError of the
+ /// specification.
+ /// Otherwise, returns <code>PP_OK</code>, but it doesn't necessarily mean
+ /// that the server received the message.
+ int32_t SendMessage(const Var& message);
/// GetBufferedAmount() returns the number of bytes of text and binary
/// messages that have been queued for the WebSocket connection to send but
/// have not been transmitted to the network yet.
///
- /// Note: This interface might not be able to return exact bytes in the first
- /// release. Current WebSocket implementation can not estimate exact protocol
- /// frame overheads.
- ///
/// @return Returns the number of bytes.
uint64_t GetBufferedAmount();
+ /// GetCloseCode() returns the connection close code for the WebSocket
+ /// connection.
+ ///
+ /// @return Returns 0 if called before the close code is set.
+ uint16_t GetCloseCode();
+
+ /// GetCloseReason() returns the connection close reason for the WebSocket
+ /// connection.
+ ///
+ /// @return Returns a <code>Var</code> of string type. If called before the
+ /// close reason is set, it contains an empty string.
+ Var GetCloseReason();
+
+ /// GetCloseWasClean() returns if the connection was closed cleanly for the
+ /// specified WebSocket connection.
+ ///
+ /// @return Returns <code>false</code> if called before the connection is
+ /// closed, or called on an invalid resource. Otherwise, returns
+ /// <code>true</code> if the connection was closed cleanly, or returns
+ /// <code>false</code> if the connection was closed for abnormal reasons.
+ bool GetCloseWasClean();
+
/// GetExtensions() returns the extensions selected by the server for the
/// specified WebSocket connection.
///
- /// @return Returns a <code>PP_VARTYPE_STRING</code> var. If called before
- /// the connection is established, its data is empty string.
- /// Currently its data is always empty string.
+ /// @return Returns a <code>Var</code> of string type. If called before the
+ /// connection is established, its data is an empty string.
+ /// Currently its data is always an empty string.
Var GetExtensions();
/// GetProtocol() returns the sub-protocol chosen by the server for the
/// specified WebSocket connection.
///
- /// @return Returns a <code>PP_VARTYPE_STRING</code> var. If called before
- /// the connection is established, its data is empty string.
+ /// @return Returns a <code>Var</code> of string type. If called before the
+ /// connection is established, it contains the empty string.
Var GetProtocol();
/// GetReadyState() returns the ready state of the specified WebSocket
@@ -111,23 +173,9 @@ class WebSocket_Dev : public Resource {
/// GetURL() returns the URL associated with specified WebSocket connection.
///
- /// @return Returns a <code>PP_VARTYPE_STRING</code> var. If called before
- /// the connection is established, its data is empty string.
+ /// @return Returns a <code>Var</code> of string type. If called before the
+ /// connection is established, it contains the empty string.
Var GetURL();
-
- /// OnOpen() is invoked when the connection is established by Connect().
- virtual void OnOpen() = 0;
-
- /// OnMessage() is invoked when a message is received.
- virtual void OnMessage(Var message) = 0;
-
- /// OnError() is invoked if the user agent was required to fail the WebSocket
- /// connection or the WebSocket connection is closed with prejudice.
- /// OnClose() always follows OnError().
- virtual void OnError() = 0;
-
- /// OnClose() is invoked when the connection is closed by errors or Close().
- virtual void OnClose(bool wasClean, uint16_t code, const Var& reason) = 0;
};
} // namespace pp
diff --git a/ppapi/ppapi_sources.gypi b/ppapi/ppapi_sources.gypi
index e4fb62f..00323d6 100644
--- a/ppapi/ppapi_sources.gypi
+++ b/ppapi/ppapi_sources.gypi
@@ -211,6 +211,8 @@
'cpp/dev/video_decoder_client_dev.h',
'cpp/dev/video_decoder_dev.cc',
'cpp/dev/video_decoder_dev.h',
+ 'cpp/dev/websocket_dev.cc',
+ 'cpp/dev/websocket_dev.h',
'cpp/dev/widget_client_dev.cc',
'cpp/dev/widget_client_dev.h',
'cpp/dev/widget_dev.cc',
diff --git a/ppapi/tests/test_websocket.cc b/ppapi/tests/test_websocket.cc
index c990113..ae1db54 100644
--- a/ppapi/tests/test_websocket.cc
+++ b/ppapi/tests/test_websocket.cc
@@ -5,6 +5,7 @@
#include "ppapi/tests/test_websocket.h"
#include <string.h>
+#include <vector>
#include "ppapi/c/dev/ppb_testing_dev.h"
#include "ppapi/c/dev/ppb_websocket_dev.h"
@@ -13,6 +14,7 @@
#include "ppapi/c/pp_completion_callback.h"
#include "ppapi/c/ppb_core.h"
#include "ppapi/c/ppb_var.h"
+#include "ppapi/cpp/dev/websocket_dev.h"
#include "ppapi/cpp/instance.h"
#include "ppapi/cpp/module.h"
#include "ppapi/tests/test_utils.h"
@@ -21,6 +23,9 @@
const char kEchoServerURL[] =
"ws://localhost:8880/websocket/tests/hybi/echo";
+const char kCloseServerURL[] =
+ "ws://localhost:8880/websocket/tests/hybi/close";
+
const char kProtocolTestServerURL[] =
"ws://localhost:8880/websocket/tests/hybi/protocol-test?protocol=";
@@ -62,6 +67,8 @@ void TestWebSocket::RunTests(const std::string& filter) {
RUN_TEST_WITH_REFERENCE_CHECK(ValidClose, filter);
RUN_TEST_WITH_REFERENCE_CHECK(GetProtocol, filter);
RUN_TEST_WITH_REFERENCE_CHECK(TextSendReceive, filter);
+
+ RUN_TEST_WITH_REFERENCE_CHECK(CcInterfaces, filter);
}
PP_Var TestWebSocket::CreateVar(const char* string) {
@@ -414,3 +421,58 @@ std::string TestWebSocket::TestTextSendReceive() {
// TODO(toyoshim): Add tests for didReceiveMessageError().
// TODO(toyoshim): Add other function tests.
+
+std::string TestWebSocket::TestCcInterfaces() {
+ // C++ bindings is simple straightforward, then just verifies interfaces work
+ // as a interface bridge fine.
+ pp::WebSocket_Dev ws(instance_);
+
+ // Check uninitialized properties access.
+ ASSERT_EQ(0, ws.GetBufferedAmount());
+ ASSERT_EQ(0, ws.GetCloseCode());
+ ASSERT_TRUE(AreEqual(ws.GetCloseReason().pp_var(), ""));
+ ASSERT_EQ(false, ws.GetCloseWasClean());
+ ASSERT_TRUE(AreEqual(ws.GetExtensions().pp_var(), ""));
+ ASSERT_TRUE(AreEqual(ws.GetProtocol().pp_var(), ""));
+ ASSERT_EQ(PP_WEBSOCKETREADYSTATE_INVALID_DEV, ws.GetReadyState());
+ ASSERT_TRUE(AreEqual(ws.GetURL().pp_var(), ""));
+
+ // Check communication interfaces (connect, send, receive, and close).
+ TestCompletionCallback connect_callback(instance_->pp_instance());
+ int32_t result = ws.Connect(pp::Var(std::string(kCloseServerURL)), NULL, 0U,
+ connect_callback);
+ ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
+ result = connect_callback.WaitForResult();
+ ASSERT_EQ(PP_OK, result);
+
+ std::string message("hello C++");
+ result = ws.SendMessage(pp::Var(message));
+ ASSERT_EQ(PP_OK, result);
+
+ pp::Var receive_var;
+ TestCompletionCallback receive_callback(instance_->pp_instance());
+ result = ws.ReceiveMessage(&receive_var, receive_callback);
+ if (result == PP_OK_COMPLETIONPENDING)
+ result = receive_callback.WaitForResult();
+ ASSERT_EQ(PP_OK, result);
+ ASSERT_TRUE(AreEqual(receive_var.pp_var(), message.c_str()));
+
+ TestCompletionCallback close_callback(instance_->pp_instance());
+ std::string reason("bye");
+ result = ws.Close(kCloseCodeNormalClosure, pp::Var(reason), close_callback);
+ ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
+ result = close_callback.WaitForResult();
+ ASSERT_EQ(PP_OK, result);
+
+ // Check initialized properties access.
+ ASSERT_EQ(0, ws.GetBufferedAmount());
+ ASSERT_EQ(kCloseCodeNormalClosure, ws.GetCloseCode());
+ ASSERT_TRUE(AreEqual(ws.GetCloseReason().pp_var(), reason.c_str()));
+ ASSERT_EQ(true, ws.GetCloseWasClean());
+ ASSERT_TRUE(AreEqual(ws.GetExtensions().pp_var(), ""));
+ ASSERT_TRUE(AreEqual(ws.GetProtocol().pp_var(), ""));
+ ASSERT_EQ(PP_WEBSOCKETREADYSTATE_CLOSED_DEV, ws.GetReadyState());
+ ASSERT_TRUE(AreEqual(ws.GetURL().pp_var(), kCloseServerURL));
+
+ PASS();
+}
diff --git a/ppapi/tests/test_websocket.h b/ppapi/tests/test_websocket.h
index 6cdf028..4048458 100644
--- a/ppapi/tests/test_websocket.h
+++ b/ppapi/tests/test_websocket.h
@@ -39,6 +39,8 @@ class TestWebSocket : public TestCase {
std::string TestGetProtocol();
std::string TestTextSendReceive();
+ std::string TestCcInterfaces();
+
// Used by the tests that access the C API directly.
const PPB_WebSocket_Dev* websocket_interface_;
const PPB_Var* var_interface_;