1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "extensions/browser/api/socket/socket.h"
8 #include "base/lazy_instance.h"
9 #include "extensions/browser/api/api_resource_manager.h"
10 #include "net/base/address_list.h"
11 #include "net/base/io_buffer.h"
12 #include "net/base/ip_endpoint.h"
13 #include "net/base/net_errors.h"
14 #include "net/socket/socket.h"
16 namespace extensions
{
18 const char kSocketTypeNotSupported
[] = "Socket type does not support this API";
20 static base::LazyInstance
<
21 BrowserContextKeyedAPIFactory
<ApiResourceManager
<Socket
> > > g_factory
=
22 LAZY_INSTANCE_INITIALIZER
;
26 BrowserContextKeyedAPIFactory
<ApiResourceManager
<Socket
> >*
27 ApiResourceManager
<Socket
>::GetFactoryInstance() {
28 return g_factory
.Pointer();
31 Socket::Socket(const std::string
& owner_extension_id
)
32 : ApiResource(owner_extension_id
), is_connected_(false) {}
35 // Derived destructors should make sure the socket has been closed.
36 DCHECK(!is_connected_
);
39 void Socket::Write(scoped_refptr
<net::IOBuffer
> io_buffer
,
41 const CompletionCallback
& callback
) {
42 DCHECK(!callback
.is_null());
43 write_queue_
.push(WriteRequest(io_buffer
, byte_count
, callback
));
47 void Socket::WriteData() {
49 if (io_buffer_write_
.get())
52 WriteRequest
& request
= write_queue_
.front();
54 DCHECK(request
.byte_count
>= request
.bytes_written
);
55 io_buffer_write_
= new net::WrappedIOBuffer(request
.io_buffer
->data() +
56 request
.bytes_written
);
58 WriteImpl(io_buffer_write_
.get(),
59 request
.byte_count
- request
.bytes_written
,
60 base::Bind(&Socket::OnWriteComplete
, base::Unretained(this)));
62 if (result
!= net::ERR_IO_PENDING
)
63 OnWriteComplete(result
);
66 void Socket::OnWriteComplete(int result
) {
67 io_buffer_write_
= NULL
;
69 WriteRequest
& request
= write_queue_
.front();
72 request
.bytes_written
+= result
;
73 if (request
.bytes_written
< request
.byte_count
) {
77 DCHECK(request
.bytes_written
== request
.byte_count
);
78 result
= request
.bytes_written
;
81 request
.callback
.Run(result
);
84 if (!write_queue_
.empty())
88 bool Socket::SetKeepAlive(bool enable
, int delay
) { return false; }
90 bool Socket::SetNoDelay(bool no_delay
) { return false; }
92 int Socket::Listen(const std::string
& address
,
95 std::string
* error_msg
) {
96 *error_msg
= kSocketTypeNotSupported
;
97 return net::ERR_FAILED
;
100 void Socket::Accept(const AcceptCompletionCallback
& callback
) {
101 callback
.Run(net::ERR_FAILED
, NULL
);
105 bool Socket::StringAndPortToIPEndPoint(const std::string
& ip_address_str
,
107 net::IPEndPoint
* ip_end_point
) {
108 DCHECK(ip_end_point
);
109 net::IPAddressNumber ip_number
;
110 if (!net::ParseIPLiteralToNumber(ip_address_str
, &ip_number
))
113 *ip_end_point
= net::IPEndPoint(ip_number
, port
);
117 bool Socket::StringAndPortToAddressList(const std::string
& ip_address_str
,
119 net::AddressList
* address_list
) {
120 DCHECK(address_list
);
121 net::IPAddressNumber ip_number
;
122 if (!net::ParseIPLiteralToNumber(ip_address_str
, &ip_number
))
125 *address_list
= net::AddressList::CreateFromIPAddress(ip_number
, port
);
129 void Socket::IPEndPointToStringAndPort(const net::IPEndPoint
& address
,
130 std::string
* ip_address_str
,
132 DCHECK(ip_address_str
);
134 *ip_address_str
= address
.ToStringWithoutPort();
135 if (ip_address_str
->empty()) {
138 *port
= address
.port();
142 Socket::WriteRequest::WriteRequest(scoped_refptr
<net::IOBuffer
> io_buffer
,
144 const CompletionCallback
& callback
)
145 : io_buffer(io_buffer
),
146 byte_count(byte_count
),
150 Socket::WriteRequest::~WriteRequest() {}
152 } // namespace extensions