summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormiket@chromium.org <miket@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-04-17 02:07:47 +0000
committermiket@chromium.org <miket@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-04-17 02:07:47 +0000
commit097fef767b3d04bda91e4731343e7ddb9c7b2e9c (patch)
tree5fa08c3cef6c8a2339beb53788e8b6146247f535
parent882898c6d48782b52dfbb52d067170e836b68cb8 (diff)
downloadchromium_src-097fef767b3d04bda91e4731343e7ddb9c7b2e9c.zip
chromium_src-097fef767b3d04bda91e4731343e7ddb9c7b2e9c.tar.gz
chromium_src-097fef767b3d04bda91e4731343e7ddb9c7b2e9c.tar.bz2
- Changed the data structure being passed around in the socket API from a string to an array of longs. This is a stepping stone to get us to ArrayBuffers.
- Changed "message" key to "data" for consistency. BUG=120567 TEST=no new ones, but existing, as updated, still pass. Review URL: http://codereview.chromium.org/10095020 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@132512 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/extensions/api/api_resource_event_notifier.cc9
-rw-r--r--chrome/browser/extensions/api/api_resource_event_notifier.h9
-rw-r--r--chrome/browser/extensions/api/serial/serial_api.cc8
-rw-r--r--chrome/browser/extensions/api/socket/socket.cc56
-rw-r--r--chrome/browser/extensions/api/socket/socket.h23
-rw-r--r--chrome/browser/extensions/api/socket/socket_api.cc56
-rw-r--r--chrome/browser/extensions/api/socket/socket_api.h8
-rw-r--r--chrome/browser/extensions/api/socket/tcp_socket_unittest.cc14
-rw-r--r--chrome/browser/extensions/api/socket/udp_socket_unittest.cc13
-rw-r--r--chrome/common/extensions/api/experimental.socket.idl9
-rw-r--r--chrome/test/data/extensions/api_test/socket/api/background.js122
11 files changed, 191 insertions, 136 deletions
diff --git a/chrome/browser/extensions/api/api_resource_event_notifier.cc b/chrome/browser/extensions/api/api_resource_event_notifier.cc
index 8a157e9..6b09023 100644
--- a/chrome/browser/extensions/api/api_resource_event_notifier.cc
+++ b/chrome/browser/extensions/api/api_resource_event_notifier.cc
@@ -6,6 +6,7 @@
#include "base/bind.h"
#include "base/json/json_writer.h"
+#include "base/values.h"
#include "chrome/browser/extensions/extension_event_router.h"
#include "chrome/browser/profiles/profile.h"
#include "content/public/browser/browser_thread.h"
@@ -50,18 +51,20 @@ void APIResourceEventNotifier::OnConnectComplete(int result_code) {
}
void APIResourceEventNotifier::OnDataRead(int result_code,
- const std::string& data) {
+ base::ListValue* data) {
// Do we have a destination for this event? There will be one if a source id
// was injected by the request handler for the resource's create method in
// schema_generated_bindings.js, which will in turn be the case if the caller
// of the create method provided an onEvent closure.
- if (src_id_ < 0)
+ if (src_id_ < 0) {
+ delete data;
return;
+ }
DictionaryValue* event = CreateAPIResourceEvent(
API_RESOURCE_EVENT_DATA_READ);
event->SetInteger(kResultCodeKey, result_code);
- event->SetString(kDataKey, data);
+ event->Set(kDataKey, data);
DispatchEvent(event);
}
diff --git a/chrome/browser/extensions/api/api_resource_event_notifier.h b/chrome/browser/extensions/api/api_resource_event_notifier.h
index d9bb226..eb16a01 100644
--- a/chrome/browser/extensions/api/api_resource_event_notifier.h
+++ b/chrome/browser/extensions/api/api_resource_event_notifier.h
@@ -16,6 +16,10 @@
class ExtensionEventRouter;
class Profile;
+namespace base {
+class ListValue;
+}
+
namespace extensions {
enum APIResourceEventType {
@@ -47,7 +51,10 @@ class APIResourceEventNotifier
virtual ~APIResourceEventNotifier();
virtual void OnConnectComplete(int result_code);
- virtual void OnDataRead(int result_code, const std::string& data);
+
+ // Takes ownership of data.
+ virtual void OnDataRead(int result_code, base::ListValue* data);
+
virtual void OnWriteComplete(int result_code);
static std::string APIResourceEventTypeToString(
diff --git a/chrome/browser/extensions/api/serial/serial_api.cc b/chrome/browser/extensions/api/serial/serial_api.cc
index 26b523f..c99c456 100644
--- a/chrome/browser/extensions/api/serial/serial_api.cc
+++ b/chrome/browser/extensions/api/serial/serial_api.cc
@@ -13,7 +13,7 @@
namespace extensions {
const char kConnectionIdKey[] = "connectionId";
-const char kMessageKey[] = "message";
+const char kDataKey[] = "data";
const char kBytesReadKey[] = "bytesRead";
const char kBytesWrittenKey[] = "bytesWritten";
@@ -81,19 +81,19 @@ bool SerialReadFunction::Prepare() {
void SerialReadFunction::Work() {
int bytes_read = -1;
- std::string message;
+ std::string data;
SerialConnection* serial_connection =
controller()->GetSerialConnection(connection_id_);
if (serial_connection) {
unsigned char byte = '\0';
bytes_read = serial_connection->Read(&byte);
if (bytes_read == 1)
- message = byte;
+ data = byte;
}
DictionaryValue* result = new DictionaryValue();
result->SetInteger(kBytesReadKey, bytes_read);
- result->SetString(kMessageKey, message);
+ result->SetString(kDataKey, data);
result_.reset(result);
}
diff --git a/chrome/browser/extensions/api/socket/socket.cc b/chrome/browser/extensions/api/socket/socket.cc
index 9dd51ce..60e57b7 100644
--- a/chrome/browser/extensions/api/socket/socket.cc
+++ b/chrome/browser/extensions/api/socket/socket.cc
@@ -18,8 +18,7 @@ Socket::Socket(const std::string& address, int port,
: APIResource(APIResource::SocketResource, event_notifier),
address_(address),
port_(port),
- is_connected_(false),
- read_buffer_(new net::IOBufferWithSize(kMaxRead)) {
+ is_connected_(false) {
}
Socket::~Socket() {
@@ -27,47 +26,34 @@ Socket::~Socket() {
DCHECK(!is_connected_);
}
-void Socket::OnDataRead(int result) {
- std::string message;
- if (result >= 0)
- message = std::string(read_buffer_->data(), result);
- event_notifier()->OnDataRead(result, message);
+void Socket::OnDataRead(scoped_refptr<net::IOBuffer> io_buffer, int result) {
+ // OnDataRead will take ownership of data_value.
+ ListValue* data_value = new ListValue();
+ if (result >= 0) {
+ size_t bytes_size = static_cast<size_t>(result);
+ 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]));
+ }
+ }
+ event_notifier()->OnDataRead(result, data_value);
}
void Socket::OnWriteComplete(int result) {
event_notifier()->OnWriteComplete(result);
}
-std::string Socket::Read() {
- int result = socket()->Read(
- read_buffer_, kMaxRead,
- base::Bind(&Socket::OnDataRead, base::Unretained(this)));
- if (result == net::ERR_IO_PENDING)
- return "";
- if (result < 0)
- return "";
- return std::string(read_buffer_->data(), result);
+int Socket::Read(scoped_refptr<net::IOBuffer> io_buffer, int io_buffer_len) {
+ return socket()->Read(
+ io_buffer.get(),
+ io_buffer_len,
+ base::Bind(&Socket::OnDataRead, base::Unretained(this), io_buffer));
}
-int Socket::Write(const std::string& message) {
- int length = message.length();
- scoped_refptr<net::StringIOBuffer> io_buffer(
- new net::StringIOBuffer(message));
- scoped_refptr<net::DrainableIOBuffer> buffer(
- new net::DrainableIOBuffer(io_buffer, length));
-
- int bytes_sent = 0;
- while (buffer->BytesRemaining()) {
- int result = socket()->Write(
- buffer, buffer->BytesRemaining(),
- base::Bind(&Socket::OnWriteComplete, base::Unretained(this)));
- if (result <= 0)
- // We pass all errors, including ERROR_IO_PENDING, back to the caller.
- return bytes_sent > 0 ? bytes_sent : result;
- bytes_sent += result;
- buffer->DidConsume(result);
- }
- return bytes_sent;
+int Socket::Write(scoped_refptr<net::IOBuffer> io_buffer, int byte_count) {
+ return socket()->Write(
+ io_buffer.get(), byte_count,
+ base::Bind(&Socket::OnWriteComplete, base::Unretained(this)));
}
} // namespace extensions
diff --git a/chrome/browser/extensions/api/socket/socket.h b/chrome/browser/extensions/api/socket/socket.h
index 37d2b57..eb9d83e 100644
--- a/chrome/browser/extensions/api/socket/socket.h
+++ b/chrome/browser/extensions/api/socket/socket.h
@@ -31,21 +31,18 @@ class Socket : public APIResource {
virtual int Connect() = 0;
virtual void Disconnect() = 0;
- // Returns a string representing what was able to be read without blocking.
- // If it reads an empty string, or blocks... the behavior is
- // indistinguishable! TODO(miket): this is awful. We should be returning a
- // blob, and we should be giving the caller all needed information about
- // what's happening with the read operation.
- virtual std::string Read();
+ // Returns the number of bytes read into the buffer, or a negative number if
+ // an error occurred.
+ virtual int Read(scoped_refptr<net::IOBuffer> io_buffer, int io_buffer_size);
// Returns the number of bytes successfully written, or a negative error
// code. Note that ERR_IO_PENDING means that the operation blocked, in which
- // case |event_notifier| will eventually be called with the final result
- // (again, either a nonnegative number of bytes written, or a negative
- // error).
- virtual int Write(const std::string& message);
+ // case |event_notifier| (supplied at socket creation) will eventually be
+ // called with the final result (again, either a nonnegative number of bytes
+ // written, or a negative error).
+ virtual int Write(scoped_refptr<net::IOBuffer> io_buffer, int bytes);
- virtual void OnDataRead(int result);
+ virtual void OnDataRead(scoped_refptr<net::IOBuffer> io_buffer, int result);
virtual void OnWriteComplete(int result);
protected:
@@ -56,10 +53,6 @@ class Socket : public APIResource {
const std::string address_;
int port_;
bool is_connected_;
-
- private:
- static const int kMaxRead = 1024;
- scoped_refptr<net::IOBufferWithSize> read_buffer_;
};
} // namespace extensions
diff --git a/chrome/browser/extensions/api/socket/socket_api.cc b/chrome/browser/extensions/api/socket/socket_api.cc
index 1b0b1c4..08e17c9 100644
--- a/chrome/browser/extensions/api/socket/socket_api.cc
+++ b/chrome/browser/extensions/api/socket/socket_api.cc
@@ -5,17 +5,17 @@
#include "chrome/browser/extensions/api/socket/socket_api.h"
#include "base/bind.h"
-#include "base/values.h"
#include "chrome/browser/extensions/api/api_resource_controller.h"
#include "chrome/browser/extensions/api/socket/socket.h"
#include "chrome/browser/extensions/api/socket/tcp_socket.h"
#include "chrome/browser/extensions/api/socket/udp_socket.h"
#include "chrome/browser/extensions/extension_service.h"
+#include "net/base/io_buffer.h"
namespace extensions {
const char kBytesWrittenKey[] = "bytesWritten";
-const char kMessageKey[] = "message";
+const char kDataKey[] = "data";
const char kSocketIdKey[] = "socketId";
const char kTCPOption[] = "tcp";
const char kUDPOption[] = "udp";
@@ -125,13 +125,29 @@ bool SocketReadFunction::Prepare() {
}
void SocketReadFunction::Work() {
- std::string message;
+ // 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;
if (socket)
- message = socket->Read();
+ bytes_read = socket->Read(io_buffer, buffer_len);
+ // 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();
- result->SetString(kMessageKey, message);
+ ListValue* data_value = new ListValue();
+ if (bytes_read > 0) {
+ 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_.reset(result);
}
@@ -139,9 +155,33 @@ bool SocketReadFunction::Respond() {
return true;
}
+SocketWriteFunction::SocketWriteFunction()
+ : socket_id_(0),
+ io_buffer_(NULL) {
+}
+
+SocketWriteFunction::~SocketWriteFunction() {
+}
+
bool SocketWriteFunction::Prepare() {
EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &socket_id_));
- EXTENSION_FUNCTION_VALIDATE(args_->GetString(1, &message_));
+ base::ListValue *data_list_value;
+ EXTENSION_FUNCTION_VALIDATE(args_->GetList(1, &data_list_value));
+
+ 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;
}
@@ -149,8 +189,8 @@ void SocketWriteFunction::Work() {
int bytes_written = -1;
Socket* socket = controller()->GetSocket(socket_id_);
if (socket)
- bytes_written = socket->Write(message_);
- else
+ bytes_written = socket->Write(io_buffer_, io_buffer_->size());
+ else
error_ = kSocketNotFoundError;
DictionaryValue* result = new DictionaryValue();
diff --git a/chrome/browser/extensions/api/socket/socket_api.h b/chrome/browser/extensions/api/socket/socket_api.h
index 2f97bfe..a9efeaa 100644
--- a/chrome/browser/extensions/api/socket/socket_api.h
+++ b/chrome/browser/extensions/api/socket/socket_api.h
@@ -6,7 +6,9 @@
#define CHROME_BROWSER_EXTENSIONS_API_SOCKET_SOCKET_API_H_
#pragma once
+#include "base/memory/ref_counted.h"
#include "chrome/browser/extensions/api/api_function.h"
+#include "net/base/io_buffer.h"
#include <string>
@@ -99,6 +101,10 @@ class SocketReadFunction : public AsyncIOAPIFunction {
};
class SocketWriteFunction : public AsyncIOAPIFunction {
+ public:
+ SocketWriteFunction();
+ virtual ~SocketWriteFunction();
+
protected:
virtual bool Prepare() OVERRIDE;
virtual void Work() OVERRIDE;
@@ -106,7 +112,7 @@ class SocketWriteFunction : public AsyncIOAPIFunction {
private:
int socket_id_;
- std::string message_;
+ scoped_refptr<net::IOBufferWithSize> io_buffer_;
DECLARE_EXTENSION_FUNCTION_NAME("experimental.socket.write")
};
diff --git a/chrome/browser/extensions/api/socket/tcp_socket_unittest.cc b/chrome/browser/extensions/api/socket/tcp_socket_unittest.cc
index 8132e78..1573fa5 100644
--- a/chrome/browser/extensions/api/socket/tcp_socket_unittest.cc
+++ b/chrome/browser/extensions/api/socket/tcp_socket_unittest.cc
@@ -8,6 +8,7 @@
#include "chrome/browser/extensions/api/api_resource_event_notifier.h"
#include "net/base/address_list.h"
#include "net/base/completion_callback.h"
+#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
#include "net/base/rand_callback.h"
#include "net/socket/tcp_client_socket.h"
@@ -56,7 +57,9 @@ TEST(SocketTest, TestTCPSocketRead) {
EXPECT_CALL(*tcp_client_socket, Read(_, _, _))
.Times(1);
- std::string message = socket->Read();
+ scoped_refptr<net::IOBufferWithSize> io_buffer(
+ new net::IOBufferWithSize(512));
+ socket->Read(io_buffer.get(), io_buffer->size());
}
TEST(SocketTest, TestTCPSocketWrite) {
@@ -70,7 +73,9 @@ TEST(SocketTest, TestTCPSocketWrite) {
EXPECT_CALL(*tcp_client_socket, Write(_, _, _))
.Times(1);
- socket->Write("foo");
+ scoped_refptr<net::IOBufferWithSize> io_buffer(
+ new net::IOBufferWithSize(256));
+ socket->Write(io_buffer.get(), io_buffer->size());
}
TEST(SocketTest, TestTCPSocketBlockedWrite) {
@@ -87,7 +92,10 @@ TEST(SocketTest, TestTCPSocketBlockedWrite) {
.WillOnce(testing::DoAll(SaveArg<2>(&callback),
Return(net::ERR_IO_PENDING)));
- ASSERT_EQ(net::ERR_IO_PENDING, socket->Write("foo"));
+ scoped_refptr<net::IOBufferWithSize> io_buffer(new net::IOBufferWithSize(
+ 1));
+ ASSERT_EQ(net::ERR_IO_PENDING, socket->Write(io_buffer.get(),
+ io_buffer->size()));
// Good. Original call came back unable to complete. Now pretend the socket
// finished, and confirm that we passed the error back.
diff --git a/chrome/browser/extensions/api/socket/udp_socket_unittest.cc b/chrome/browser/extensions/api/socket/udp_socket_unittest.cc
index 980e3e8..b8c50a1 100644
--- a/chrome/browser/extensions/api/socket/udp_socket_unittest.cc
+++ b/chrome/browser/extensions/api/socket/udp_socket_unittest.cc
@@ -7,6 +7,7 @@
#include "base/memory/scoped_ptr.h"
#include "chrome/browser/extensions/api/api_resource_event_notifier.h"
#include "net/base/completion_callback.h"
+#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
#include "net/base/rand_callback.h"
#include "net/udp/udp_client_socket.h"
@@ -56,7 +57,9 @@ TEST(SocketTest, TestUDPSocketRead) {
EXPECT_CALL(*udp_client_socket, Read(_, _, _))
.Times(1);
- std::string message = socket->Read();
+ scoped_refptr<net::IOBufferWithSize> io_buffer(
+ new net::IOBufferWithSize(512));
+ socket->Read(io_buffer.get(), io_buffer->size());
}
TEST(SocketTest, TestUDPSocketWrite) {
@@ -69,7 +72,9 @@ TEST(SocketTest, TestUDPSocketWrite) {
EXPECT_CALL(*udp_client_socket, Write(_, _, _))
.Times(1);
- socket->Write("foo");
+ scoped_refptr<net::IOBufferWithSize> io_buffer(
+ new net::IOBufferWithSize(512));
+ socket->Write(io_buffer.get(), io_buffer->size());
}
TEST(SocketTest, TestUDPSocketBlockedWrite) {
@@ -85,7 +90,9 @@ TEST(SocketTest, TestUDPSocketBlockedWrite) {
.WillOnce(testing::DoAll(SaveArg<2>(&callback),
Return(net::ERR_IO_PENDING)));
- ASSERT_EQ(net::ERR_IO_PENDING, socket->Write("foo"));
+ scoped_refptr<net::IOBufferWithSize> io_buffer(new net::IOBufferWithSize(1));
+ ASSERT_EQ(net::ERR_IO_PENDING, socket->Write(io_buffer.get(),
+ io_buffer->size()));
// Good. Original call came back unable to complete. Now pretend the socket
// finished, and confirm that we passed the error back.
diff --git a/chrome/common/extensions/api/experimental.socket.idl b/chrome/common/extensions/api/experimental.socket.idl
index 70a99b2..b919b81 100644
--- a/chrome/common/extensions/api/experimental.socket.idl
+++ b/chrome/common/extensions/api/experimental.socket.idl
@@ -19,7 +19,8 @@
long? resultCode;
// The data read, if the event type is dataRead.
- DOMString? data;
+ // TODO(miket): [instanceOf=ArrayBuffer]object? data;
+ long[]? data;
// Whether this is the final event that this socket will send.
[nodoc] boolean isFinalEvent;
@@ -53,7 +54,8 @@
dictionary ReadInfo {
// The data received. Warning: will probably become a blob or other
// appropriate binary-friendly type.
- DOMString message;
+ // TODO(miket): [instanceOf=ArrayBuffer]object data;
+ long[] data;
};
callback ReadCallback = void (ReadInfo readInfo);
@@ -111,8 +113,9 @@
// write operation completes without blocking, the write operation blocked
// before completion (in which case onEvent() will eventually be called with
// a <code>writeComplete</code> event), or an error occurred.
+ // TODO(miket): [instanceOf=ArrayBuffer]object data;
static void write(long socketId,
- DOMString data,
+ long[] data,
WriteCallback callback);
};
diff --git a/chrome/test/data/extensions/api_test/socket/api/background.js b/chrome/test/data/extensions/api_test/socket/api/background.js
index cb799a7..576fd2e 100644
--- a/chrome/test/data/extensions/api_test/socket/api/background.js
+++ b/chrome/test/data/extensions/api_test/socket/api/background.js
@@ -2,47 +2,63 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// net/tools/testserver/testserver.py is picky about the format of what it
+// calls its "echo" messages. One might go so far as to mutter to oneself that
+// it isn't an echo server at all.
+//
+// The response is based on the request but obfuscated using a random key.
+const request = "0100000005320000005hello";
+var expectedResponsePattern = /0100000005320000005.{11}/;
+
const socket = chrome.experimental.socket;
-const message = "helloECHO";
-const address = "127.0.0.1";
-var protocol = "none";
+var address;
+var bytesWritten = 0;
+var dataAsString;
+var dataRead = [];
var port = -1;
+var protocol = "none";
var socketId = 0;
-var dataRead = "";
var succeeded = false;
var waitCount = 0;
-var testSocketCreation = function() {
- function onCreate(socketInfo) {
- chrome.test.assertTrue(socketInfo.socketId > 0);
+// Many thanks to Dennis for his StackOverflow answer: http://goo.gl/UDanx
+function string2ArrayBuffer(string, callback) {
+ var bb = new WebKitBlobBuilder();
+ bb.append(string);
+ var f = new FileReader();
+ f.onload = function(e) {
+ callback(e.target.result);
+ };
+ f.readAsArrayBuffer(bb.getBlob());
+}
- // TODO(miket): this doesn't work yet. It's possible this will become
- // automatic, but either way we can't forget to clean up.
- //socket.destroy(socketInfo.socketId);
+function arrayBuffer2String(buf, callback) {
+ var bb = new WebKitBlobBuilder();
+ bb.append(buf);
+ var f = new FileReader();
+ f.onload = function(e) {
+ callback(e.target.result);
+ };
+ f.readAsText(bb.getBlob());
+}
- chrome.test.succeed();
+function arrayBufferToArrayOfLongs(arrayBuffer) {
+ var longs = [];
+ var arrayBufferView = new Uint8Array(arrayBuffer);
+ for (var i = 0; i < arrayBufferView.length; ++i) {
+ longs[i] = arrayBufferView[i];
}
+ return longs;
+}
- socket.create(protocol, address, port, {}, onCreate);
-};
-
-// net/tools/testserver/testserver.py is picky about the format of what
-// it calls its "echo" messages. One might go so far as to mutter to
-// oneself that it isn't an echo server at all.
-//
-// The response is based on the request but obfuscated using a random
-// key.
-const request = "0100000005320000005hello";
-var expectedResponsePattern = /0100000005320000005.{11}/;
-
-var address;
-var protocol;
-var port;
-var socketId = 0;
-var bytesWritten = 0;
-var dataRead = "";
-var succeeded = false;
-var waitCount = 0;
+function arrayOfLongsToArrayBuffer(longs) {
+ var arrayBuffer = new ArrayBuffer(longs.length);
+ var arrayBufferView = new Uint8Array(arrayBuffer);
+ for (var i = 0; i < longs.length; ++i) {
+ arrayBufferView[i] = longs[i];
+ }
+ return arrayBuffer;
+}
var testSocketCreation = function() {
function onCreate(socketInfo) {
@@ -50,6 +66,7 @@ var testSocketCreation = function() {
// TODO(miket): this doesn't work yet. It's possible this will become
// automatic, but either way we can't forget to clean up.
+ //
//socket.destroy(socketInfo.socketId);
chrome.test.succeed();
@@ -59,11 +76,14 @@ var testSocketCreation = function() {
};
function onDataRead(readInfo) {
- dataRead += readInfo.message;
- if (dataRead.match(expectedResponsePattern)) {
- succeeded = true;
- chrome.test.succeed();
- }
+ // TODO(miket): this isn't correct for multiple calls of onDataRead.
+ arrayBuffer2String(arrayOfLongsToArrayBuffer(readInfo.data), function(s) {
+ dataAsString = s; // save this for error reporting
+ if (s.match(expectedResponsePattern)) {
+ succeeded = true;
+ chrome.test.succeed();
+ }
+ });
// Blocked. Wait for onEvent.
}
@@ -77,7 +97,10 @@ function onWriteComplete(writeInfo) {
function onConnectComplete(connectResult) {
if (connectResult == 0) {
- socket.write(socketId, request, onWriteComplete);
+ string2ArrayBuffer(request, function(arrayBuffer) {
+ var longs = arrayBufferToArrayOfLongs(arrayBuffer);
+ socket.write(socketId, longs, onWriteComplete);
+ });
}
// Blocked. Wait for onEvent.
}
@@ -92,8 +115,7 @@ function onEvent(socketEvent) {
if (socketEvent.type == "connectComplete") {
onConnectComplete(socketEvent.resultCode);
} else if (socketEvent.type == "dataRead") {
- // TODO(miket): why one "message" and the other "data"?
- onDataRead({message: socketEvent.data});
+ onDataRead({data: socketEvent.data});
} else if (socketEvent.type == "writeComplete") {
onWriteComplete(socketEvent.resultCode);
} else {
@@ -101,33 +123,13 @@ function onEvent(socketEvent) {
}
};
-function onRead(readInfo) {
- if (readInfo.message == message) {
- succeeded = true;
- chrome.test.succeed();
- } else {
- // The read blocked. Save what we've got so far, and wait for onEvent.
- dataRead = readInfo.message;
- }
-}
-
-function onWrite(writeInfo) {
- chrome.test.assertTrue(writeInfo.bytesWritten == message.length);
- socket.read(socketId, onRead);
-}
-
-function onConnect(connectResult) {
- chrome.test.assertTrue(connectResult);
- socket.write(socketId, message, onWrite);
-}
-
function waitForBlockingOperation() {
if (++waitCount < 10) {
setTimeout(waitForBlockingOperation, 1000);
} else {
// We weren't able to succeed in the given time.
chrome.test.fail("Operations didn't complete after " + waitCount + " " +
- "seconds. Response so far was <" + dataRead + ">.");
+ "seconds. Response so far was <" + dataAsString + ">.");
}
}