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/private/tcp_socket_private.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/pp_bool.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/pp_errors.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)
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace pp {
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template <> const char* interface_name<PPB_TCPSocket_Private_0_5>() {
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return PPB_TCPSOCKET_PRIVATE_INTERFACE_0_5;
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <> const char* interface_name<PPB_TCPSocket_Private_0_4>() {
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return PPB_TCPSOCKET_PRIVATE_INTERFACE_0_4;
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <> const char* interface_name<PPB_TCPSocket_Private_0_3>() {
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return PPB_TCPSOCKET_PRIVATE_INTERFACE_0_3;
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TCPSocketPrivate::TCPSocketPrivate(const InstanceHandle& instance) {
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (has_interface<PPB_TCPSocket_Private_0_5>()) {
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PassRefFromConstructor(get_interface<PPB_TCPSocket_Private_0_5>()->Create(
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        instance.pp_instance()));
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else if (has_interface<PPB_TCPSocket_Private_0_4>()) {
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PassRefFromConstructor(get_interface<PPB_TCPSocket_Private_0_4>()->Create(
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        instance.pp_instance()));
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (has_interface<PPB_TCPSocket_Private_0_3>()) {
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PassRefFromConstructor(get_interface<PPB_TCPSocket_Private_0_3>()->Create(
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        instance.pp_instance()));
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TCPSocketPrivate::TCPSocketPrivate(PassRef, PP_Resource resource)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : Resource(PASS_REF, resource) {
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TCPSocketPrivate::IsAvailable() {
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return has_interface<PPB_TCPSocket_Private_0_5>() ||
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      has_interface<PPB_TCPSocket_Private_0_4>() ||
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      has_interface<PPB_TCPSocket_Private_0_3>();
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int32_t TCPSocketPrivate::Connect(const char* host,
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  uint16_t port,
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  const CompletionCallback& callback) {
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (has_interface<PPB_TCPSocket_Private_0_5>()) {
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return get_interface<PPB_TCPSocket_Private_0_5>()->Connect(
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        pp_resource(), host, port, callback.pp_completion_callback());
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (has_interface<PPB_TCPSocket_Private_0_4>()) {
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return get_interface<PPB_TCPSocket_Private_0_4>()->Connect(
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        pp_resource(), host, port, callback.pp_completion_callback());
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (has_interface<PPB_TCPSocket_Private_0_3>()) {
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return get_interface<PPB_TCPSocket_Private_0_3>()->Connect(
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        pp_resource(), host, port, callback.pp_completion_callback());
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return callback.MayForce(PP_ERROR_NOINTERFACE);
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int32_t TCPSocketPrivate::ConnectWithNetAddress(
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const PP_NetAddress_Private* addr,
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const CompletionCallback& callback) {
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (has_interface<PPB_TCPSocket_Private_0_5>()) {
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return get_interface<PPB_TCPSocket_Private_0_5>()->ConnectWithNetAddress(
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        pp_resource(), addr, callback.pp_completion_callback());
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (has_interface<PPB_TCPSocket_Private_0_4>()) {
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return get_interface<PPB_TCPSocket_Private_0_4>()->ConnectWithNetAddress(
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        pp_resource(), addr, callback.pp_completion_callback());
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (has_interface<PPB_TCPSocket_Private_0_3>()) {
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return get_interface<PPB_TCPSocket_Private_0_3>()->ConnectWithNetAddress(
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        pp_resource(), addr, callback.pp_completion_callback());
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return callback.MayForce(PP_ERROR_NOINTERFACE);
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TCPSocketPrivate::GetLocalAddress(PP_NetAddress_Private* local_addr) {
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (has_interface<PPB_TCPSocket_Private_0_5>()) {
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PP_Bool result = get_interface<PPB_TCPSocket_Private_0_5>()->
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        GetLocalAddress(pp_resource(), local_addr);
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return PP_ToBool(result);
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (has_interface<PPB_TCPSocket_Private_0_4>()) {
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PP_Bool result = get_interface<PPB_TCPSocket_Private_0_4>()->
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GetLocalAddress(pp_resource(), local_addr);
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return PP_ToBool(result);
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (has_interface<PPB_TCPSocket_Private_0_3>()) {
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PP_Bool result = get_interface<PPB_TCPSocket_Private_0_3>()->
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GetLocalAddress(pp_resource(), local_addr);
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return PP_ToBool(result);
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TCPSocketPrivate::GetRemoteAddress(PP_NetAddress_Private* remote_addr) {
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (has_interface<PPB_TCPSocket_Private_0_5>()) {
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PP_Bool result = get_interface<PPB_TCPSocket_Private_0_5>()->
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        GetRemoteAddress(pp_resource(), remote_addr);
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return PP_ToBool(result);
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (has_interface<PPB_TCPSocket_Private_0_4>()) {
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PP_Bool result = get_interface<PPB_TCPSocket_Private_0_4>()->
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GetRemoteAddress(pp_resource(), remote_addr);
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return PP_ToBool(result);
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (has_interface<PPB_TCPSocket_Private_0_3>()) {
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PP_Bool result = get_interface<PPB_TCPSocket_Private_0_3>()->
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GetRemoteAddress(pp_resource(), remote_addr);
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return PP_ToBool(result);
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int32_t TCPSocketPrivate::SSLHandshake(const char* server_name,
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       uint16_t server_port,
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       const CompletionCallback& callback) {
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (has_interface<PPB_TCPSocket_Private_0_5>()) {
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return get_interface<PPB_TCPSocket_Private_0_5>()->SSLHandshake(
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        pp_resource(), server_name, server_port,
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        callback.pp_completion_callback());
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (has_interface<PPB_TCPSocket_Private_0_4>()) {
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return get_interface<PPB_TCPSocket_Private_0_4>()->SSLHandshake(
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        pp_resource(), server_name, server_port,
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        callback.pp_completion_callback());
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (has_interface<PPB_TCPSocket_Private_0_3>()) {
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return get_interface<PPB_TCPSocket_Private_0_3>()->SSLHandshake(
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        pp_resource(), server_name, server_port,
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        callback.pp_completion_callback());
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return callback.MayForce(PP_ERROR_NOINTERFACE);
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)X509CertificatePrivate TCPSocketPrivate::GetServerCertificate() {
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (has_interface<PPB_TCPSocket_Private_0_5>()) {
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return X509CertificatePrivate(PASS_REF,
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        get_interface<PPB_TCPSocket_Private_0_5>()->GetServerCertificate(
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            pp_resource()));
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (has_interface<PPB_TCPSocket_Private_0_4>()) {
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return X509CertificatePrivate(PASS_REF,
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        get_interface<PPB_TCPSocket_Private_0_4>()->GetServerCertificate(
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            pp_resource()));
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return X509CertificatePrivate();
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TCPSocketPrivate::AddChainBuildingCertificate(
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const X509CertificatePrivate& cert,
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool trusted) {
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (has_interface<PPB_TCPSocket_Private_0_5>()) {
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return PP_ToBool(get_interface<PPB_TCPSocket_Private_0_5>()->
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        AddChainBuildingCertificate(pp_resource(), cert.pp_resource(),
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                    PP_FromBool(trusted)));
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (has_interface<PPB_TCPSocket_Private_0_4>()) {
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return PP_ToBool(get_interface<PPB_TCPSocket_Private_0_4>()->
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AddChainBuildingCertificate(pp_resource(), cert.pp_resource(),
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    PP_FromBool(trusted)));
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int32_t TCPSocketPrivate::Read(char* buffer,
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               int32_t bytes_to_read,
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               const CompletionCallback& callback) {
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (has_interface<PPB_TCPSocket_Private_0_5>()) {
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return get_interface<PPB_TCPSocket_Private_0_5>()->Read(
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        pp_resource(), buffer, bytes_to_read,
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        callback.pp_completion_callback());
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (has_interface<PPB_TCPSocket_Private_0_4>()) {
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return get_interface<PPB_TCPSocket_Private_0_4>()->Read(
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        pp_resource(), buffer, bytes_to_read,
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        callback.pp_completion_callback());
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (has_interface<PPB_TCPSocket_Private_0_3>()) {
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return get_interface<PPB_TCPSocket_Private_0_3>()->Read(
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        pp_resource(), buffer, bytes_to_read,
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        callback.pp_completion_callback());
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return callback.MayForce(PP_ERROR_NOINTERFACE);
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int32_t TCPSocketPrivate::Write(const char* buffer,
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                int32_t bytes_to_write,
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                const CompletionCallback& callback) {
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (has_interface<PPB_TCPSocket_Private_0_5>()) {
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return get_interface<PPB_TCPSocket_Private_0_5>()->Write(
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        pp_resource(), buffer, bytes_to_write,
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        callback.pp_completion_callback());
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (has_interface<PPB_TCPSocket_Private_0_4>()) {
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return get_interface<PPB_TCPSocket_Private_0_4>()->Write(
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        pp_resource(), buffer, bytes_to_write,
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        callback.pp_completion_callback());
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (has_interface<PPB_TCPSocket_Private_0_3>()) {
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return get_interface<PPB_TCPSocket_Private_0_3>()->Write(
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        pp_resource(), buffer, bytes_to_write,
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        callback.pp_completion_callback());
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return callback.MayForce(PP_ERROR_NOINTERFACE);
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TCPSocketPrivate::Disconnect() {
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (has_interface<PPB_TCPSocket_Private_0_5>()) {
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return get_interface<PPB_TCPSocket_Private_0_5>()->Disconnect(
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        pp_resource());
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (has_interface<PPB_TCPSocket_Private_0_4>()) {
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return get_interface<PPB_TCPSocket_Private_0_4>()->Disconnect(
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        pp_resource());
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (has_interface<PPB_TCPSocket_Private_0_3>()) {
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return get_interface<PPB_TCPSocket_Private_0_3>()->Disconnect(
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        pp_resource());
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int32_t TCPSocketPrivate::SetOption(PP_TCPSocketOption_Private name,
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                    const Var& value,
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                    const CompletionCallback& callback) {
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (has_interface<PPB_TCPSocket_Private_0_5>()) {
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return get_interface<PPB_TCPSocket_Private_0_5>()->SetOption(
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        pp_resource(), name, value.pp_var(), callback.pp_completion_callback());
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return callback.MayForce(PP_ERROR_NOINTERFACE);
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace pp
249