Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(136)

Side by Side Diff: webkit/plugins/ppapi/ppb_websocket_impl.cc

Issue 8774042: WebSocket Pepper API: ArrayBuffer support (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: sync path had a bug Created 8 years, 12 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « ppapi/tests/test_websocket.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "webkit/plugins/ppapi/ppb_websocket_impl.h" 5 #include "webkit/plugins/ppapi/ppb_websocket_impl.h"
6 6
7 #include <set> 7 #include <set>
8 #include <string> 8 #include <string>
9 9
10 #include "base/basictypes.h" 10 #include "base/basictypes.h"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "googleurl/src/gurl.h" 12 #include "googleurl/src/gurl.h"
13 #include "net/base/net_util.h" 13 #include "net/base/net_util.h"
14 #include "ppapi/c/dev/ppb_var_array_buffer_dev.h"
14 #include "ppapi/c/pp_completion_callback.h" 15 #include "ppapi/c/pp_completion_callback.h"
15 #include "ppapi/c/pp_errors.h" 16 #include "ppapi/c/pp_errors.h"
16 #include "ppapi/c/pp_var.h" 17 #include "ppapi/c/pp_var.h"
17 #include "ppapi/c/ppb_var.h" 18 #include "ppapi/c/ppb_var.h"
18 #include "ppapi/shared_impl/var.h" 19 #include "ppapi/shared_impl/var.h"
19 #include "ppapi/shared_impl/var_tracker.h" 20 #include "ppapi/shared_impl/var_tracker.h"
20 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebData.h" 21 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebData.h"
21 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h" 22 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h"
22 #include "third_party/WebKit/Source/WebKit/chromium/public/WebElement.h" 23 #include "third_party/WebKit/Source/WebKit/chromium/public/WebElement.h"
23 #include "third_party/WebKit/Source/WebKit/chromium/public/WebPluginContainer.h" 24 #include "third_party/WebKit/Source/WebKit/chromium/public/WebPluginContainer.h"
24 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h" 25 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h"
25 #include "third_party/WebKit/Source/WebKit/chromium/public/WebSocket.h" 26 #include "third_party/WebKit/Source/WebKit/chromium/public/WebSocket.h"
26 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebURL.h" 27 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebURL.h"
27 #include "webkit/plugins/ppapi/host_globals.h" 28 #include "webkit/plugins/ppapi/host_globals.h"
28 #include "webkit/plugins/ppapi/ppapi_plugin_instance.h" 29 #include "webkit/plugins/ppapi/ppapi_plugin_instance.h"
29 #include "webkit/plugins/ppapi/resource_helper.h" 30 #include "webkit/plugins/ppapi/resource_helper.h"
30 31
32 using ppapi::ArrayBufferVar;
31 using ppapi::PpapiGlobals; 33 using ppapi::PpapiGlobals;
32 using ppapi::StringVar; 34 using ppapi::StringVar;
33 using ppapi::thunk::PPB_WebSocket_API; 35 using ppapi::thunk::PPB_WebSocket_API;
34 using ppapi::VarTracker; 36 using ppapi::VarTracker;
35 using WebKit::WebData; 37 using WebKit::WebData;
36 using WebKit::WebDocument; 38 using WebKit::WebDocument;
37 using WebKit::WebString; 39 using WebKit::WebString;
38 using WebKit::WebSocket; 40 using WebKit::WebSocket;
39 using WebKit::WebSocketClient; 41 using WebKit::WebSocketClient;
40 using WebKit::WebURL; 42 using WebKit::WebURL;
41 43
42 const uint32_t kMaxReasonSizeInBytes = 123; 44 const uint32_t kMaxReasonSizeInBytes = 123;
43 const size_t kHybiBaseFramingOverhead = 2; 45 const size_t kHybiBaseFramingOverhead = 2;
44 const size_t kHybiMaskingKeyLength = 4; 46 const size_t kHybiMaskingKeyLength = 4;
45 const size_t kMinimumPayloadSizeWithTwoByteExtendedPayloadLength = 126; 47 const size_t kMinimumPayloadSizeWithTwoByteExtendedPayloadLength = 126;
46 const size_t kMinimumPayloadSizeWithEightByteExtendedPayloadLength = 0x10000; 48 const size_t kMinimumPayloadSizeWithEightByteExtendedPayloadLength = 0x10000;
47 49
48 namespace { 50 namespace {
49 51
50 uint64_t SaturateAdd(uint64_t a, uint64_t b) { 52 uint64_t SaturateAdd(uint64_t a, uint64_t b) {
51 if (kuint64max - a < b) 53 if (kuint64max - a < b)
52 return kuint64max; 54 return kuint64max;
53 return a + b; 55 return a + b;
54 } 56 }
55 57
56 uint64_t GetFrameSize(uint64_t payload_size) { 58 uint64_t GetFrameSize(uint64_t payload_size) {
57 if (!payload_size)
58 return 0;
59
60 uint64_t overhead = kHybiBaseFramingOverhead + kHybiMaskingKeyLength; 59 uint64_t overhead = kHybiBaseFramingOverhead + kHybiMaskingKeyLength;
61 if (payload_size > kMinimumPayloadSizeWithEightByteExtendedPayloadLength) 60 if (payload_size > kMinimumPayloadSizeWithEightByteExtendedPayloadLength)
62 overhead += 8; 61 overhead += 8;
63 else if (payload_size > kMinimumPayloadSizeWithTwoByteExtendedPayloadLength) 62 else if (payload_size > kMinimumPayloadSizeWithTwoByteExtendedPayloadLength)
64 overhead += 2; 63 overhead += 2;
65 return SaturateAdd(payload_size, overhead); 64 return SaturateAdd(payload_size, overhead);
66 } 65 }
67 66
68 bool InValidStateToReceive(PP_WebSocketReadyState_Dev state) { 67 bool InValidStateToReceive(PP_WebSocketReadyState_Dev state) {
69 return state == PP_WEBSOCKETREADYSTATE_OPEN_DEV || 68 return state == PP_WEBSOCKETREADYSTATE_OPEN_DEV ||
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
277 } 276 }
278 277
279 int32_t PPB_WebSocket_Impl::ReceiveMessage(PP_Var* message, 278 int32_t PPB_WebSocket_Impl::ReceiveMessage(PP_Var* message,
280 PP_CompletionCallback callback) { 279 PP_CompletionCallback callback) {
281 // Check state. 280 // Check state.
282 if (state_ == PP_WEBSOCKETREADYSTATE_INVALID_DEV || 281 if (state_ == PP_WEBSOCKETREADYSTATE_INVALID_DEV ||
283 state_ == PP_WEBSOCKETREADYSTATE_CONNECTING_DEV) 282 state_ == PP_WEBSOCKETREADYSTATE_CONNECTING_DEV)
284 return PP_ERROR_BADARGUMENT; 283 return PP_ERROR_BADARGUMENT;
285 284
286 // Just return received message if any received message is queued. 285 // Just return received message if any received message is queued.
287 if (!received_messages_.empty()) 286 if (!received_messages_.empty()) {
287 receive_callback_var_ = message;
288 return DoReceive(); 288 return DoReceive();
289 }
289 290
290 // Check state again. In CLOSED state, no more messages will be received. 291 // Check state again. In CLOSED state, no more messages will be received.
291 if (state_ == PP_WEBSOCKETREADYSTATE_CLOSED_DEV) 292 if (state_ == PP_WEBSOCKETREADYSTATE_CLOSED_DEV)
292 return PP_ERROR_BADARGUMENT; 293 return PP_ERROR_BADARGUMENT;
293 294
294 // Returns PP_ERROR_FAILED after an error is received and received messages 295 // Returns PP_ERROR_FAILED after an error is received and received messages
295 // is exhausted. 296 // is exhausted.
296 if (error_was_received_) 297 if (error_was_received_)
297 return PP_ERROR_FAILED; 298 return PP_ERROR_FAILED;
298 299
(...skipping 20 matching lines...) Expand all
319 return PP_ERROR_BADARGUMENT; 320 return PP_ERROR_BADARGUMENT;
320 321
321 if (state_ == PP_WEBSOCKETREADYSTATE_CLOSING_DEV || 322 if (state_ == PP_WEBSOCKETREADYSTATE_CLOSING_DEV ||
322 state_ == PP_WEBSOCKETREADYSTATE_CLOSED_DEV) { 323 state_ == PP_WEBSOCKETREADYSTATE_CLOSED_DEV) {
323 // Handle buffered_amount_after_close_. 324 // Handle buffered_amount_after_close_.
324 uint64_t payload_size = 0; 325 uint64_t payload_size = 0;
325 if (message.type == PP_VARTYPE_STRING) { 326 if (message.type == PP_VARTYPE_STRING) {
326 scoped_refptr<StringVar> message_string = StringVar::FromPPVar(message); 327 scoped_refptr<StringVar> message_string = StringVar::FromPPVar(message);
327 if (message_string) 328 if (message_string)
328 payload_size += message_string->value().length(); 329 payload_size += message_string->value().length();
330 } else if (message.type == PP_VARTYPE_ARRAY_BUFFER) {
331 scoped_refptr<ArrayBufferVar> message_array_buffer =
332 ArrayBufferVar::FromPPVar(message);
333 if (message_array_buffer)
334 payload_size += message_array_buffer->ByteLength();
335 } else {
336 // TODO(toyoshim): Support Blob.
337 return PP_ERROR_NOTSUPPORTED;
329 } 338 }
330 // TODO(toyoshim): Support binary data.
331 339
332 buffered_amount_after_close_ = 340 buffered_amount_after_close_ =
333 SaturateAdd(buffered_amount_after_close_, GetFrameSize(payload_size)); 341 SaturateAdd(buffered_amount_after_close_, GetFrameSize(payload_size));
334 342
335 return PP_ERROR_FAILED; 343 return PP_ERROR_FAILED;
336 } 344 }
337 345
338 if (message.type != PP_VARTYPE_STRING) { 346 // Send the message.
339 // TODO(toyoshim): Support binary data. 347 if (message.type == PP_VARTYPE_STRING) {
348 // Convert message to WebString.
349 scoped_refptr<StringVar> message_string = StringVar::FromPPVar(message);
350 if (!message_string)
351 return PP_ERROR_BADARGUMENT;
352 WebString web_message = WebString::fromUTF8(message_string->value());
353 if (!websocket_->sendText(web_message))
354 return PP_ERROR_BADARGUMENT;
355 } else if (message.type == PP_VARTYPE_ARRAY_BUFFER) {
356 // Convert message to WebData.
357 // TODO(toyoshim): Must add a WebKit interface which handles WebArrayBuffer
358 // directly.
359 scoped_refptr<ArrayBufferVar> message_array_buffer =
360 ArrayBufferVar::FromPPVar(message);
361 if (!message_array_buffer)
362 return PP_ERROR_BADARGUMENT;
363 WebData web_message = WebData(
364 static_cast<const char*>(message_array_buffer->Map()),
365 static_cast<size_t>(message_array_buffer->ByteLength()));
366 if (!websocket_->sendBinary(web_message))
367 return PP_ERROR_BADARGUMENT;
368 } else {
369 // TODO(toyoshim): Support Blob.
340 return PP_ERROR_NOTSUPPORTED; 370 return PP_ERROR_NOTSUPPORTED;
341 } 371 }
342 372
343 // Convert message to WebString.
344 scoped_refptr<StringVar> message_string = StringVar::FromPPVar(message);
345 if (!message_string)
346 return PP_ERROR_BADARGUMENT;
347 WebString web_message = WebString::fromUTF8(message_string->value());
348 if (!websocket_->sendText(web_message))
349 return PP_ERROR_BADARGUMENT;
350
351 return PP_OK; 373 return PP_OK;
352 } 374 }
353 375
354 uint64_t PPB_WebSocket_Impl::GetBufferedAmount() { 376 uint64_t PPB_WebSocket_Impl::GetBufferedAmount() {
355 return SaturateAdd(buffered_amount_, buffered_amount_after_close_); 377 return SaturateAdd(buffered_amount_, buffered_amount_after_close_);
356 } 378 }
357 379
358 uint16_t PPB_WebSocket_Impl::GetCloseCode() { 380 uint16_t PPB_WebSocket_Impl::GetCloseCode() {
359 return close_code_; 381 return close_code_;
360 } 382 }
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
416 return; 438 return;
417 439
418 PP_RunAndClearCompletionCallback(&receive_callback_, DoReceive()); 440 PP_RunAndClearCompletionCallback(&receive_callback_, DoReceive());
419 } 441 }
420 442
421 void PPB_WebSocket_Impl::didReceiveBinaryData(const WebData& binaryData) { 443 void PPB_WebSocket_Impl::didReceiveBinaryData(const WebData& binaryData) {
422 // Dispose packets after receiving an error or in invalid state. 444 // Dispose packets after receiving an error or in invalid state.
423 if (error_was_received_ || !InValidStateToReceive(state_)) 445 if (error_was_received_ || !InValidStateToReceive(state_))
424 return; 446 return;
425 447
426 // TODO(toyoshim): Support to receive binary data. 448 // Append received data to queue.
427 DLOG(INFO) << "didReceiveBinaryData is not implemented yet."; 449 PP_Var var = PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferPPVar(
450 binaryData.size());
451 scoped_refptr<ArrayBufferVar> arraybuffer = ArrayBufferVar::FromPPVar(var);
452 void* data = arraybuffer->Map();
453 memcpy(data, binaryData.data(), binaryData.size());
454 received_messages_.push(var);
455
456 if (!wait_for_receive_)
457 return;
458
459 PP_RunAndClearCompletionCallback(&receive_callback_, DoReceive());
428 } 460 }
429 461
430 void PPB_WebSocket_Impl::didReceiveMessageError() { 462 void PPB_WebSocket_Impl::didReceiveMessageError() {
431 // Ignore error notification in invalid state. 463 // Ignore error notification in invalid state.
432 if (!InValidStateToReceive(state_)) 464 if (!InValidStateToReceive(state_))
433 return; 465 return;
434 466
435 // Records the error, then stops receiving any frames after this error. 467 // Records the error, then stops receiving any frames after this error.
436 // The error will be notified after all queued messages are read via 468 // The error will be notified after all queued messages are read via
437 // ReceiveMessage(). 469 // ReceiveMessage().
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
504 536
505 *receive_callback_var_ = received_messages_.front(); 537 *receive_callback_var_ = received_messages_.front();
506 received_messages_.pop(); 538 received_messages_.pop();
507 receive_callback_var_ = NULL; 539 receive_callback_var_ = NULL;
508 wait_for_receive_ = false; 540 wait_for_receive_ = false;
509 return PP_OK; 541 return PP_OK;
510 } 542 }
511 543
512 } // namespace ppapi 544 } // namespace ppapi
513 } // namespace webkit 545 } // namespace webkit
OLDNEW
« no previous file with comments | « ppapi/tests/test_websocket.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698