15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/websocket.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/pp_errors.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/pp_macros.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/completion_callback.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/instance_handle.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/module.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/module_impl.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/var.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace pp {
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <> const char* interface_name<PPB_WebSocket_1_0>() {
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return PPB_WEBSOCKET_INTERFACE_1_0;
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WebSocket::WebSocket(const InstanceHandle& instance) {
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!has_interface<PPB_WebSocket_1_0>())
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PassRefFromConstructor(get_interface<PPB_WebSocket_1_0>()->Create(
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    instance.pp_instance()));
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WebSocket::~WebSocket() {
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int32_t WebSocket::Connect(const Var& url, const Var protocols[],
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint32_t protocol_count, const CompletionCallback& callback) {
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!has_interface<PPB_WebSocket_1_0>())
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return PP_ERROR_BADRESOURCE;
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Convert protocols to C interface.
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PP_Var *c_protocols = NULL;
428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (protocol_count)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    c_protocols = new PP_Var[protocol_count];
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (uint32_t i = 0; i < protocol_count; ++i)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    c_protocols[i] = protocols[i].pp_var();
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int32_t result = get_interface<PPB_WebSocket_1_0>()->Connect(
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pp_resource(), url.pp_var(), c_protocols, protocol_count,
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      callback.pp_completion_callback());
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (c_protocols)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delete[] c_protocols;
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int32_t WebSocket::Close(uint16_t code, const Var& reason,
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const CompletionCallback& callback) {
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!has_interface<PPB_WebSocket_1_0>())
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return PP_ERROR_BADRESOURCE;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return get_interface<PPB_WebSocket_1_0>()->Close(
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pp_resource(), code, reason.pp_var(),
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      callback.pp_completion_callback());
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int32_t WebSocket::ReceiveMessage(Var* message,
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const CompletionCallback& callback) {
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!has_interface<PPB_WebSocket_1_0>())
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return PP_ERROR_BADRESOURCE;
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Initialize |message| to release old internal PP_Var of reused |message|.
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (message)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *message = Var();
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return get_interface<PPB_WebSocket_1_0>()->ReceiveMessage(
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pp_resource(), const_cast<PP_Var*>(&message->pp_var()),
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      callback.pp_completion_callback());
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int32_t WebSocket::SendMessage(const Var& message) {
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!has_interface<PPB_WebSocket_1_0>())
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return PP_ERROR_BADRESOURCE;
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return get_interface<PPB_WebSocket_1_0>()->SendMessage(
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pp_resource(), message.pp_var());
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)uint64_t WebSocket::GetBufferedAmount() {
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!has_interface<PPB_WebSocket_1_0>())
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return 0;
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return get_interface<PPB_WebSocket_1_0>()->GetBufferedAmount(pp_resource());
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)uint16_t WebSocket::GetCloseCode() {
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!has_interface<PPB_WebSocket_1_0>())
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return 0;
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return get_interface<PPB_WebSocket_1_0>()->GetCloseCode(pp_resource());
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Var WebSocket::GetCloseReason() {
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!has_interface<PPB_WebSocket_1_0>())
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return 0;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return Var(PASS_REF,
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      get_interface<PPB_WebSocket_1_0>()->GetCloseReason(pp_resource()));
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WebSocket::GetCloseWasClean() {
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!has_interface<PPB_WebSocket_1_0>())
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PP_Bool result =
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      get_interface<PPB_WebSocket_1_0>()->GetCloseWasClean(pp_resource());
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return PP_ToBool(result);
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Var WebSocket::GetExtensions() {
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!has_interface<PPB_WebSocket_1_0>())
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return Var();
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return Var(PASS_REF,
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             get_interface<PPB_WebSocket_1_0>()->GetExtensions(pp_resource()));
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Var WebSocket::GetProtocol() {
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!has_interface<PPB_WebSocket_1_0>())
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return Var();
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return Var(PASS_REF,
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             get_interface<PPB_WebSocket_1_0>()->GetProtocol(pp_resource()));
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_WebSocketReadyState WebSocket::GetReadyState() {
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!has_interface<PPB_WebSocket_1_0>())
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return PP_WEBSOCKETREADYSTATE_INVALID;
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return get_interface<PPB_WebSocket_1_0>()->GetReadyState(pp_resource());
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Var WebSocket::GetURL() {
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!has_interface<PPB_WebSocket_1_0>())
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return Var();
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return Var(PASS_REF,
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             get_interface<PPB_WebSocket_1_0>()->GetURL(pp_resource()));
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace pp
150