OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2011 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. | |
4 | |
5 #include "ppapi/shared_impl/udp_socket_impl.h" | |
6 | |
7 #include <string.h> | |
8 #include <algorithm> | |
yzshen1
2011/11/29 20:19:33
an empty line between c and c++ headers, please.
ygorshenin
2011/11/30 11:50:54
Done.
| |
9 | |
10 #include "base/basictypes.h" | |
11 #include "base/logging.h" | |
12 #include "ppapi/c/pp_errors.h" | |
13 | |
14 namespace ppapi { | |
15 | |
16 const int32_t UDPSocketImpl::kMaxReadSize = 1024 * 1024; | |
17 const int32_t UDPSocketImpl::kMaxWriteSize = 1024 * 1024; | |
18 | |
19 UDPSocketImpl::UDPSocketImpl(const HostResource& resource, uint32 socket_id) | |
20 : Resource(resource) { | |
21 Init(socket_id); | |
22 } | |
23 | |
24 UDPSocketImpl::UDPSocketImpl(PP_Instance instance, uint32 socket_id) | |
25 : Resource(instance) { | |
26 Init(socket_id); | |
27 } | |
28 | |
29 UDPSocketImpl::~UDPSocketImpl() { | |
30 } | |
31 | |
32 thunk::PPB_UDPSocket_Private_API* | |
33 UDPSocketImpl::AsPPB_UDPSocket_Private_API() { | |
34 return this; | |
35 } | |
36 | |
37 int32_t UDPSocketImpl::Bind(const PP_NetAddress_Private* addr, | |
38 PP_CompletionCallback callback) { | |
39 if (!addr || !callback.func) | |
40 return PP_ERROR_BADARGUMENT; | |
41 if (bound_ || closed_) | |
42 return PP_ERROR_FAILED; | |
43 if (bind_callback_.func) | |
44 return PP_ERROR_INPROGRESS; | |
45 // TODO(dmichael): use some other strategy for determining if an | |
46 // operation is in progress | |
47 | |
48 bind_callback_ = callback; | |
49 | |
50 // Send the request, the browser will call us back via BindACK. | |
51 SendBind(*addr); | |
52 return PP_OK_COMPLETIONPENDING; | |
53 } | |
54 | |
55 int32_t UDPSocketImpl::RecvFrom(char* buffer, | |
56 int32_t num_bytes, | |
57 PP_CompletionCallback callback) { | |
58 if (!buffer || num_bytes <= 0 || !callback.func) | |
59 return PP_ERROR_BADARGUMENT; | |
60 if (!bound_) | |
61 return PP_ERROR_FAILED; | |
62 if (recvfrom_callback_.func) | |
63 return PP_ERROR_INPROGRESS; | |
64 | |
65 read_buffer_ = buffer; | |
66 bytes_to_read_ = std::min(num_bytes, kMaxReadSize); | |
67 recvfrom_callback_ = callback; | |
68 | |
69 // Send the request, the browser will call us back via RecvFromACK. | |
70 SendRecvFrom(bytes_to_read_); | |
71 return PP_OK_COMPLETIONPENDING; | |
72 } | |
73 | |
74 PP_Bool UDPSocketImpl::GetRecvFromAddress(PP_NetAddress_Private* addr) { | |
75 if (!addr) | |
76 return PP_FALSE; | |
77 | |
78 *addr = recvfrom_addr_; | |
79 return PP_TRUE; | |
80 } | |
81 | |
82 int32_t UDPSocketImpl::SendTo(const char* buffer, | |
83 int32_t num_bytes, | |
84 const PP_NetAddress_Private* addr, | |
85 PP_CompletionCallback callback) { | |
86 if (!buffer || num_bytes <= 0 || !addr || !callback.func) | |
87 return PP_ERROR_BADARGUMENT; | |
88 if (!bound_) | |
89 return PP_ERROR_FAILED; | |
90 if (sendto_callback_.func) | |
91 return PP_ERROR_INPROGRESS; | |
92 | |
93 if (num_bytes > kMaxWriteSize) | |
94 num_bytes = kMaxWriteSize; | |
95 | |
96 sendto_callback_ = callback; | |
97 | |
98 // Send the request, the browser will call us back via SendToACK. | |
99 SendSendTo(std::string(buffer, num_bytes), *addr); | |
100 return PP_OK_COMPLETIONPENDING; | |
101 } | |
102 | |
103 void UDPSocketImpl::Close() { | |
104 if(closed_) | |
105 return; | |
106 | |
107 bound_ = false; | |
108 closed_ = true; | |
109 | |
110 SendClose(); | |
111 | |
112 socket_id_ = 0; | |
113 | |
114 PostAbortAndClearIfNecessary(&bind_callback_); | |
115 PostAbortAndClearIfNecessary(&recvfrom_callback_); | |
116 PostAbortAndClearIfNecessary(&sendto_callback_); | |
117 } | |
118 | |
119 void UDPSocketImpl::OnBindCompleted(bool succeeded) { | |
120 if (!bind_callback_.func) { | |
121 NOTREACHED(); | |
122 return; | |
123 } | |
124 | |
125 if (succeeded) | |
126 bound_ = true; | |
127 | |
128 PP_RunAndClearCompletionCallback(&bind_callback_, | |
129 succeeded ? PP_OK : PP_ERROR_FAILED); | |
130 } | |
131 | |
132 void UDPSocketImpl::OnRecvFromCompleted(bool succeeded, | |
133 const std::string& data, | |
134 const PP_NetAddress_Private& addr) { | |
135 if (!recvfrom_callback_.func || !read_buffer_) { | |
136 NOTREACHED(); | |
137 return; | |
138 } | |
139 | |
140 if (succeeded) { | |
141 CHECK_LE(static_cast<int32_t>(data.size()), bytes_to_read_); | |
142 if (!data.empty()) | |
143 memcpy(read_buffer_, data.c_str(), data.size()); | |
144 } | |
145 read_buffer_ = NULL; | |
146 bytes_to_read_ = -1; | |
147 recvfrom_addr_ = addr; | |
148 | |
149 PP_RunAndClearCompletionCallback( | |
150 &recvfrom_callback_, | |
151 succeeded ? static_cast<int32_t>(data.size()) : | |
152 static_cast<int32_t>(PP_ERROR_FAILED)); | |
153 } | |
154 | |
155 void UDPSocketImpl::OnSendToCompleted(bool succeeded, int32_t bytes_written) { | |
156 if (!sendto_callback_.func) { | |
157 NOTREACHED(); | |
158 return; | |
159 } | |
160 | |
161 PP_RunAndClearCompletionCallback( | |
162 &sendto_callback_, | |
163 succeeded ? bytes_written : static_cast<int32_t>(PP_ERROR_FAILED)); | |
164 } | |
165 | |
166 void UDPSocketImpl::Init(uint32 socket_id) { | |
167 DCHECK(socket_id != 0); | |
168 socket_id_ = socket_id; | |
169 bound_ = false; | |
170 closed_ = false; | |
171 bind_callback_ = PP_BlockUntilComplete(); | |
172 recvfrom_callback_ = PP_BlockUntilComplete(); | |
173 sendto_callback_ = PP_BlockUntilComplete(); | |
174 read_buffer_ = NULL; | |
175 bytes_to_read_ = -1; | |
176 | |
177 recvfrom_addr_.size = 0; | |
178 memset(recvfrom_addr_.data, 0, | |
179 arraysize(recvfrom_addr_.data) * sizeof(*recvfrom_addr_.data)); | |
180 } | |
181 | |
182 void UDPSocketImpl::PostAbortAndClearIfNecessary( | |
183 PP_CompletionCallback* callback) { | |
184 DCHECK(callback); | |
185 | |
186 if (callback->func) { | |
187 PostAbort(*callback); | |
188 *callback = PP_BlockUntilComplete(); | |
189 } | |
190 } | |
191 | |
192 } // namespace ppapi | |
OLD | NEW |