Index: chrome/browser/extensions/api/socket/socket_api.cc |
diff --git a/chrome/browser/extensions/api/socket/socket_api.cc b/chrome/browser/extensions/api/socket/socket_api.cc |
index 9e741b6adf7f17dac5b25a0955af115232641815..f00f5a5a03f3fb12a9c4685e97288933fc80159a 100644 |
--- a/chrome/browser/extensions/api/socket/socket_api.cc |
+++ b/chrome/browser/extensions/api/socket/socket_api.cc |
@@ -11,9 +11,12 @@ |
#include "chrome/browser/extensions/api/socket/udp_socket.h" |
#include "chrome/browser/extensions/extension_service.h" |
#include "net/base/io_buffer.h" |
+#include "net/base/ip_endpoint.h" |
namespace extensions { |
+const char kAddressKey[] = "address"; |
+const char kPortKey[] = "port"; |
const char kBytesWrittenKey[] = "bytesWritten"; |
const char kDataKey[] = "data"; |
const char kSocketIdKey[] = "socketId"; |
@@ -28,14 +31,7 @@ SocketCreateFunction::SocketCreateFunction() |
bool SocketCreateFunction::Prepare() { |
std::string socket_type_string; |
- size_t argument_position = 0; |
- EXTENSION_FUNCTION_VALIDATE(args_->GetString(argument_position++, |
- &socket_type_string)); |
- EXTENSION_FUNCTION_VALIDATE(args_->GetString(argument_position++, |
- &address_)); |
- EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(argument_position++, |
- &port_)); |
- |
+ EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &socket_type_string)); |
if (socket_type_string == kTCPOption) |
socket_type_ = kSocketTypeTCP; |
else if (socket_type_string == kUDPOption) |
@@ -43,7 +39,7 @@ bool SocketCreateFunction::Prepare() { |
else |
return false; |
- src_id_ = ExtractSrcId(argument_position); |
+ src_id_ = ExtractSrcId(1); |
event_notifier_ = CreateEventNotifier(src_id_); |
return true; |
@@ -52,9 +48,9 @@ bool SocketCreateFunction::Prepare() { |
void SocketCreateFunction::Work() { |
Socket* socket = NULL; |
if (socket_type_ == kSocketTypeTCP) { |
- socket = new TCPSocket(address_, port_, event_notifier_); |
+ socket = new TCPSocket(event_notifier_); |
} else { |
- socket = new UDPSocket(address_, port_, event_notifier_); |
+ socket = new UDPSocket(event_notifier_); |
} |
DCHECK(socket); |
DCHECK(socket->IsValid()); |
@@ -84,6 +80,8 @@ bool SocketDestroyFunction::Respond() { |
bool SocketConnectFunction::Prepare() { |
EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &socket_id_)); |
+ EXTENSION_FUNCTION_VALIDATE(args_->GetString(1, &address_)); |
+ EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(2, &port_)); |
return true; |
} |
@@ -91,7 +89,7 @@ void SocketConnectFunction::Work() { |
int result = -1; |
Socket* socket = controller()->GetSocket(socket_id_); |
if (socket) |
- result = socket->Connect(); |
+ result = socket->Connect(address_, port_); |
else |
error_ = kSocketNotFoundError; |
result_.reset(Value::CreateIntegerValue(result)); |
@@ -119,6 +117,29 @@ bool SocketDisconnectFunction::Respond() { |
return true; |
} |
+ |
+bool SocketBindFunction::Prepare() { |
+ EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &socket_id_)); |
+ EXTENSION_FUNCTION_VALIDATE(args_->GetString(1, &address_)); |
+ EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(2, &port_)); |
+ return true; |
+} |
+ |
+void SocketBindFunction::Work() { |
+ int result = -1; |
+ Socket* socket = controller()->GetSocket(socket_id_); |
+ if (socket) |
+ result = socket->Bind(address_, port_); |
+ else |
+ error_ = kSocketNotFoundError; |
+ |
+ result_.reset(Value::CreateIntegerValue(result)); |
+} |
+ |
+bool SocketBindFunction::Respond() { |
+ return true; |
+} |
+ |
bool SocketReadFunction::Prepare() { |
EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &socket_id_)); |
return true; |
@@ -202,4 +223,97 @@ bool SocketWriteFunction::Respond() { |
return true; |
} |
+bool SocketRecvFromFunction::Prepare() { |
+ EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &socket_id_)); |
+ return true; |
+} |
+ |
+void SocketRecvFromFunction::Work() { |
+ // TODO(miket): this is an arbitrary number. Can we come up with one that |
+ // makes sense? |
+ const int buffer_len = 2048; |
+ scoped_refptr<net::IOBuffer> io_buffer(new net::IOBuffer(buffer_len)); |
+ Socket* socket = controller()->GetSocket(socket_id_); |
+ int bytes_read = -1; |
+ std::string ip_address_str; |
+ int port = 0; |
+ if (socket) { |
+ bytes_read = socket->RecvFrom(io_buffer, buffer_len, &address_); |
+ } |
+ |
+ // TODO(miket): the buffer-to-array functionality appears twice, once here |
+ // and once in socket.cc. When serial etc. is converted over, it'll appear |
+ // there, too. What's a good single place for it to live? Keep in mind that |
+ // this is short-term code, to be replaced with ArrayBuffer code. |
+ DictionaryValue* result = new DictionaryValue(); |
+ ListValue* data_value = new ListValue(); |
+ if (bytes_read > 0) { |
+ Socket::IPEndPointToStringAndPort(address_, &ip_address_str, &port); |
+ size_t bytes_size = static_cast<size_t>(bytes_read); |
+ const char* io_buffer_start = io_buffer->data(); |
+ for (size_t i = 0; i < bytes_size; ++i) { |
+ data_value->Set(i, Value::CreateIntegerValue(io_buffer_start[i])); |
+ } |
+ } |
+ result->Set(kDataKey, data_value); |
+ result->SetString(kAddressKey, ip_address_str); |
+ result->SetInteger(kPortKey, port); |
+ result_.reset(result); |
+} |
+ |
+bool SocketRecvFromFunction::Respond() { |
+ return true; |
+} |
+ |
+SocketSendToFunction::SocketSendToFunction() |
+ : socket_id_(0), |
+ io_buffer_(NULL) { |
+} |
+ |
+SocketSendToFunction::~SocketSendToFunction() { |
+} |
+ |
+bool SocketSendToFunction::Prepare() { |
+ EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &socket_id_)); |
+ base::ListValue *data_list_value; |
+ EXTENSION_FUNCTION_VALIDATE(args_->GetList(1, &data_list_value)); |
+ EXTENSION_FUNCTION_VALIDATE(args_->GetString(2, &address_)); |
+ EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(3, &port_)); |
+ |
+ size_t size = data_list_value->GetSize(); |
+ if (size != 0) { |
+ io_buffer_ = new net::IOBufferWithSize(size); |
+ uint8* data_buffer = |
+ reinterpret_cast<uint8*>(io_buffer_->data()); |
+ for (size_t i = 0; i < size; ++i) { |
+ int int_value = -1; |
+ data_list_value->GetInteger(i, &int_value); |
+ DCHECK(int_value < 256); |
+ DCHECK(int_value >= 0); |
+ uint8 truncated_int = static_cast<uint8>(int_value); |
+ *data_buffer++ = truncated_int; |
+ } |
+ } |
+ return true; |
+} |
+ |
+void SocketSendToFunction::Work() { |
+ int bytes_written = -1; |
+ Socket* socket = controller()->GetSocket(socket_id_); |
+ if (socket) { |
+ bytes_written = socket->SendTo(io_buffer_, io_buffer_->size(), address_, |
+ port_); |
+ } else { |
+ error_ = kSocketNotFoundError; |
+ } |
+ |
+ DictionaryValue* result = new DictionaryValue(); |
+ result->SetInteger(kBytesWrittenKey, bytes_written); |
+ result_.reset(result); |
+} |
+ |
+bool SocketSendToFunction::Respond() { |
+ return true; |
+} |
+ |
} // namespace extensions |