Index: ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_websocket.cc |
diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_websocket.cc b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_websocket.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..a24c654c13a9b5e224bd50eeeb31ce7703e4440f |
--- /dev/null |
+++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_websocket.cc |
@@ -0,0 +1,366 @@ |
+// Copyright (c) 2012 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 "native_client/src/shared/ppapi_proxy/plugin_ppb_websocket.h" |
+ |
+#include "native_client/src/include/nacl_scoped_ptr.h" |
+#include "native_client/src/shared/ppapi_proxy/object_serialize.h" |
+#include "native_client/src/shared/ppapi_proxy/plugin_callback.h" |
+#include "native_client/src/shared/ppapi_proxy/plugin_globals.h" |
+#include "native_client/src/shared/ppapi_proxy/utility.h" |
+#include "native_client/src/shared/srpc/nacl_srpc.h" |
+#include "ppapi/c/pp_completion_callback.h" |
+#include "ppapi/c/pp_errors.h" |
+#include "ppapi/c/pp_var.h" |
+#include "ppapi/c/dev/ppb_websocket_dev.h" |
+#include "srpcgen/ppb_rpc.h" |
+ |
+namespace ppapi_proxy { |
+ |
+namespace { |
+ |
+PP_Resource Create(PP_Instance instance) { |
+ DebugPrintf("PPB_WebSocket::Create: instance=%"NACL_PRId32"\n", instance); |
+ |
+ PP_Resource resource; |
+ NaClSrpcError srpc_result = |
+ PpbWebSocketRpcClient::PPB_WebSocket_Create( |
+ GetMainSrpcChannel(), instance, &resource); |
+ DebugPrintf("PPB_WebSocket::Create: %s\n", NaClSrpcErrorString(srpc_result)); |
+ |
+ if (srpc_result == NACL_SRPC_RESULT_OK) |
+ return resource; |
+ return kInvalidResourceId; |
+} |
+ |
+PP_Bool IsWebSocket(PP_Resource resource) { |
+ DebugPrintf( |
+ "PPB_WebSocket::IsWebSocket: resource=%"NACL_PRId32"\n", resource); |
+ |
+ int32_t is_websocket; |
+ NaClSrpcError srpc_result = |
+ PpbWebSocketRpcClient::PPB_WebSocket_IsWebSocket( |
+ GetMainSrpcChannel(), resource, &is_websocket); |
+ DebugPrintf("PPB_WebSocket::IsWebSocket: %s\n", |
+ NaClSrpcErrorString(srpc_result)); |
+ |
+ if (srpc_result == NACL_SRPC_RESULT_OK && is_websocket) |
+ return PP_TRUE; |
+ return PP_FALSE; |
+} |
+ |
+int32_t Connect(PP_Resource ws, |
+ PP_Var url, |
+ const PP_Var protocols[], |
+ uint32_t protocol_count, |
+ PP_CompletionCallback callback) { |
+ DebugPrintf("PPB_WebSocket::Connect: ws=%"NACL_PRId32"\n", ws); |
+ |
+ nacl_abi_size_t url_size = 0; |
+ nacl::scoped_array<char> url_bytes(Serialize(&url, 1, &url_size)); |
+ |
+ nacl_abi_size_t protocols_size = 0; |
+ nacl::scoped_array<char> protocols_bytes( |
+ Serialize(protocols, protocol_count, &protocols_size)); |
+ |
+ int32_t callback_id = CompletionCallbackTable::Get()->AddCallback(callback); |
+ if (callback_id == 0) |
+ return PP_ERROR_BLOCKS_MAIN_THREAD; |
+ |
+ int32_t pp_error; |
+ NaClSrpcError srpc_result = |
+ PpbWebSocketRpcClient::PPB_WebSocket_Connect( |
+ GetMainSrpcChannel(), |
+ ws, |
+ url_size, url_bytes.get(), |
+ protocols_size, protocols_bytes.get(), |
+ static_cast<int32_t>(protocol_count), |
+ callback_id, |
+ &pp_error); |
+ DebugPrintf("PPB_WebSocket::Connect: %s\n", |
+ NaClSrpcErrorString(srpc_result)); |
+ |
+ if (srpc_result != NACL_SRPC_RESULT_OK) |
+ pp_error = PP_ERROR_FAILED; |
+ return MayForceCallback(callback, pp_error); |
+} |
+ |
+int32_t Close(PP_Resource ws, |
+ uint16_t code, |
+ PP_Var reason, |
+ PP_CompletionCallback callback) { |
+ DebugPrintf("PPB_WebSocket::Close: ws=%"NACL_PRId32"\n", ws); |
+ |
+ nacl_abi_size_t reason_size = 0; |
+ nacl::scoped_array<char> reason_bytes(Serialize(&reason, 1, &reason_size)); |
+ |
+ int32_t callback_id = CompletionCallbackTable::Get()->AddCallback(callback); |
+ if (callback_id == 0) |
+ return PP_ERROR_BLOCKS_MAIN_THREAD; |
+ |
+ int32_t pp_error; |
+ NaClSrpcError srpc_result = |
+ PpbWebSocketRpcClient::PPB_WebSocket_Close( |
+ GetMainSrpcChannel(), |
+ ws, |
+ code, |
+ reason_size, reason_bytes.get(), |
+ callback_id, |
+ &pp_error); |
+ DebugPrintf("PPB_WebSocket::Close: %s\n", NaClSrpcErrorString(srpc_result)); |
+ |
+ if (srpc_result != NACL_SRPC_RESULT_OK) |
+ pp_error = PP_ERROR_FAILED; |
+ return MayForceCallback(callback, pp_error); |
+} |
+ |
+int32_t ReceiveMessage(PP_Resource ws, |
+ PP_Var* message, |
+ PP_CompletionCallback callback) { |
+ DebugPrintf("PPB_WebSocket::ReceiveMessage: ws=%"NACL_PRId32"\n", ws); |
+ |
+ int32_t callback_id = |
+ CompletionCallbackTable::Get()->AddCallback(callback, message); |
+ if (callback_id == 0) |
+ return PP_ERROR_BLOCKS_MAIN_THREAD; |
+ |
+ // TODO(toyoshim): ReceiveMessage needs performance optimization to reduce |
+ // chances to call RPC. |
+ int32_t pp_error; |
+ NaClSrpcError srpc_result = |
+ PpbWebSocketRpcClient::PPB_WebSocket_ReceiveMessage( |
+ GetMainSrpcChannel(), |
+ ws, |
+ callback_id, |
+ &pp_error); |
+ DebugPrintf("PPB_WebSocket::ReceiveMessage: %s\n", |
+ NaClSrpcErrorString(srpc_result)); |
+ |
+ if (srpc_result != NACL_SRPC_RESULT_OK) |
+ pp_error = PP_ERROR_FAILED; |
+ return MayForceCallback(callback, pp_error); |
+} |
+ |
+int32_t SendMessage(PP_Resource ws, |
+ PP_Var message) { |
+ DebugPrintf("PPB_WebSocket::SendMessage: ws=%"NACL_PRId32"\n", ws); |
+ |
+ nacl_abi_size_t message_size = 0; |
+ nacl::scoped_array<char> message_bytes( |
+ Serialize(&message, 1, &message_size)); |
+ |
+ int32_t pp_error; |
+ NaClSrpcError srpc_result = |
+ PpbWebSocketRpcClient::PPB_WebSocket_SendMessage( |
+ GetMainSrpcChannel(), |
+ ws, |
+ message_size, message_bytes.get(), |
+ &pp_error); |
+ DebugPrintf("PPB_WebSocket::SendMessage: %s\n", |
+ NaClSrpcErrorString(srpc_result)); |
+ |
+ if (srpc_result != NACL_SRPC_RESULT_OK) |
+ return PP_ERROR_FAILED; |
+ return pp_error; |
+} |
+ |
+uint64_t GetBufferedAmount(PP_Resource ws) { |
+ DebugPrintf("PPB_WebSocket::GetBufferedAmount: ws=%"NACL_PRId32"\n", ws); |
+ |
+ int64_t buffered_amount = 0; |
+ NaClSrpcError srpc_result = |
+ PpbWebSocketRpcClient::PPB_WebSocket_GetBufferedAmount( |
+ GetMainSrpcChannel(), ws, &buffered_amount); |
+ DebugPrintf("PPB_WebSocket::GetBufferedAmount: %s\n", |
+ NaClSrpcErrorString(srpc_result)); |
+ |
+ return static_cast<uint64_t>(buffered_amount); |
+} |
+ |
+uint16_t GetCloseCode(PP_Resource ws) { |
+ DebugPrintf("PPB_WebSocket::GetCloseCode: ws=%"NACL_PRId32"\n", ws); |
+ |
+ int32_t close_code = 0; |
+ NaClSrpcError srpc_result = |
+ PpbWebSocketRpcClient::PPB_WebSocket_GetCloseCode( |
+ GetMainSrpcChannel(), ws, &close_code); |
+ DebugPrintf("PPB_WebSocket::GetCloseCode: %s\n", |
+ NaClSrpcErrorString(srpc_result)); |
+ |
+ return static_cast<uint16_t>(close_code); |
+} |
+ |
+PP_Var GetCloseReason(PP_Resource ws) { |
+ DebugPrintf("PPB_WebSocket::GetCloseReason: ws=%"NACL_PRId32"\n", ws); |
+ |
+ nacl_abi_size_t reason_size = kMaxReturnVarSize; |
+ nacl::scoped_array<char> reason_bytes(new char[reason_size]); |
+ NaClSrpcError srpc_result = |
+ PpbWebSocketRpcClient::PPB_WebSocket_GetCloseReason( |
+ GetMainSrpcChannel(), ws, &reason_size, reason_bytes.get()); |
+ DebugPrintf("PPB_WebSocket::GetCloseReason: %s\n", |
+ NaClSrpcErrorString(srpc_result)); |
+ |
+ if (srpc_result == NACL_SRPC_RESULT_OK) { |
+ PP_Var reason = PP_MakeUndefined(); |
+ if (DeserializeTo(reason_bytes.get(), reason_size, 1, &reason)) |
+ return reason; |
+ } |
+ |
+ return PP_MakeUndefined(); |
+} |
+ |
+PP_Bool GetCloseWasClean(PP_Resource ws) { |
+ DebugPrintf( |
+ "PPB_WebSocket::GetCloseWasClean: ws=%"NACL_PRId32"\n", ws); |
+ |
+ int32_t was_clean; |
+ NaClSrpcError srpc_result = |
+ PpbWebSocketRpcClient::PPB_WebSocket_GetCloseWasClean( |
+ GetMainSrpcChannel(), ws, &was_clean); |
+ DebugPrintf("PPB_WebSocket::GetCloseWasClean: %s\n", |
+ NaClSrpcErrorString(srpc_result)); |
+ |
+ if (srpc_result == NACL_SRPC_RESULT_OK && was_clean) |
+ return PP_TRUE; |
+ return PP_FALSE; |
+} |
+ |
+PP_Var GetExtensions(PP_Resource ws) { |
+ DebugPrintf("PPB_WebSocket::GetExtensions: ws=%"NACL_PRId32"\n", ws); |
+ |
+ nacl_abi_size_t extensions_size = kMaxReturnVarSize; |
+ nacl::scoped_array<char> extensions_bytes(new char[extensions_size]); |
+ NaClSrpcError srpc_result = |
+ PpbWebSocketRpcClient::PPB_WebSocket_GetExtensions( |
+ GetMainSrpcChannel(), ws, &extensions_size, extensions_bytes.get()); |
+ DebugPrintf("PPB_WebSocket::GetExtensions: %s\n", |
+ NaClSrpcErrorString(srpc_result)); |
+ |
+ if (srpc_result == NACL_SRPC_RESULT_OK) { |
+ PP_Var extensions = PP_MakeUndefined(); |
+ if (DeserializeTo(extensions_bytes.get(), extensions_size, 1, &extensions)) |
+ return extensions; |
+ } |
+ |
+ return PP_MakeUndefined(); |
+} |
+ |
+PP_Var GetProtocol(PP_Resource ws) { |
+ DebugPrintf("PPB_WebSocket::GetProtocol: ws=%"NACL_PRId32"\n", ws); |
+ |
+ nacl_abi_size_t protocol_size = kMaxReturnVarSize; |
+ nacl::scoped_array<char> protocol_bytes(new char[protocol_size]); |
+ NaClSrpcError srpc_result = |
+ PpbWebSocketRpcClient::PPB_WebSocket_GetProtocol( |
+ GetMainSrpcChannel(), ws, &protocol_size, protocol_bytes.get()); |
+ DebugPrintf("PPB_WebSocket::GetProtocol: %s\n", |
+ NaClSrpcErrorString(srpc_result)); |
+ |
+ if (srpc_result == NACL_SRPC_RESULT_OK) { |
+ PP_Var protocol = PP_MakeUndefined(); |
+ if (DeserializeTo(protocol_bytes.get(), protocol_size, 1, &protocol)) |
+ return protocol; |
+ } |
+ |
+ return PP_MakeUndefined(); |
+} |
+ |
+PP_WebSocketReadyState_Dev GetReadyState(PP_Resource ws) { |
+ DebugPrintf( |
+ "PPB_WebSocket::GetReadyState: ws=%"NACL_PRId32"\n", ws); |
+ |
+ int32_t ready_state; |
+ NaClSrpcError srpc_result = |
+ PpbWebSocketRpcClient::PPB_WebSocket_GetReadyState( |
+ GetMainSrpcChannel(), ws, &ready_state); |
+ DebugPrintf("PPB_WebSocket::GetReadyState: %s\n", |
+ NaClSrpcErrorString(srpc_result)); |
+ |
+ if (srpc_result != NACL_SRPC_RESULT_OK) |
+ return PP_WEBSOCKETREADYSTATE_INVALID_DEV; |
+ return static_cast<PP_WebSocketReadyState_Dev>(ready_state); |
+} |
+ |
+PP_Var GetURL(PP_Resource ws) { |
+ DebugPrintf("PPB_WebSocket::GetURL: ws=%"NACL_PRId32"\n", ws); |
+ |
+ nacl_abi_size_t url_size = kMaxReturnVarSize; |
+ nacl::scoped_array<char> url_bytes(new char[url_size]); |
+ NaClSrpcError srpc_result = |
+ PpbWebSocketRpcClient::PPB_WebSocket_GetURL( |
+ GetMainSrpcChannel(), ws, &url_size, url_bytes.get()); |
+ DebugPrintf("PPB_WebSocket::GetURL: %s\n", |
+ NaClSrpcErrorString(srpc_result)); |
+ |
+ if (srpc_result == NACL_SRPC_RESULT_OK) { |
+ PP_Var url = PP_MakeUndefined(); |
+ if (DeserializeTo(url_bytes.get(), url_size, 1, &url)) |
+ return url; |
+ } |
+ |
+ return PP_MakeUndefined(); |
+} |
+ |
+PP_Bool SetBinaryType(PP_Resource ws, |
+ PP_WebSocketBinaryType_Dev binary_type) { |
+ DebugPrintf("PPB_WebSocket::SetBinaryType: ws=%"NACL_PRId32"\n", ws); |
+ |
+ int32_t success; |
+ NaClSrpcError srpc_result = |
+ PpbWebSocketRpcClient::PPB_WebSocket_SetBinaryType( |
+ GetMainSrpcChannel(), |
+ ws, |
+ static_cast<int32_t>(binary_type), |
+ &success); |
+ DebugPrintf("PPB_WebSocket::SetBinaryType: %s\n", |
+ NaClSrpcErrorString(srpc_result)); |
+ |
+ if (srpc_result == NACL_SRPC_RESULT_OK && success) |
+ return PP_TRUE; |
+ return PP_FALSE; |
+} |
+ |
+PP_WebSocketBinaryType_Dev GetBinaryType(PP_Resource ws) { |
+ DebugPrintf("PPB_WebSocket::GetBinaryType: ws=%"NACL_PRId32"\n", ws); |
+ |
+ int32_t binary_type; |
+ NaClSrpcError srpc_result = |
+ PpbWebSocketRpcClient::PPB_WebSocket_GetBinaryType( |
+ GetMainSrpcChannel(), |
+ ws, |
+ &binary_type); |
+ DebugPrintf("PPB_WebSocket::GetBinaryType: %s\n", |
+ NaClSrpcErrorString(srpc_result)); |
+ |
+ if (srpc_result != NACL_SRPC_RESULT_OK) |
+ return PP_WEBSOCKETBINARYTYPE_INVALID; |
+ return static_cast<PP_WebSocketBinaryType_Dev>(binary_type); |
+} |
+ |
+} // namespace |
+ |
+const PPB_WebSocket_Dev* PluginWebSocket::GetInterface() { |
+ static const PPB_WebSocket_Dev websocket_interface = { |
+ &Create, |
+ &IsWebSocket, |
+ &Connect, |
+ &Close, |
+ &ReceiveMessage, |
+ &SendMessage, |
+ &GetBufferedAmount, |
+ &GetCloseCode, |
+ &GetCloseReason, |
+ &GetCloseWasClean, |
+ &GetExtensions, |
+ &GetProtocol, |
+ &GetReadyState, |
+ &GetURL, |
+ &SetBinaryType, |
+ &GetBinaryType |
+ }; |
+ return &websocket_interface; |
+} |
+ |
+} // namespace ppapi_proxy |