1a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
2a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// found in the LICENSE file.
4a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
5a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "mojo/bindings/js/core.h"
6a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
7a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/bind.h"
8a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/logging.h"
9a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "gin/arguments.h"
10a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "gin/array_buffer.h"
11a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "gin/converter.h"
12a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "gin/dictionary.h"
13a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "gin/function_template.h"
14c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "gin/handle.h"
15a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "gin/object_template_builder.h"
16a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "gin/per_isolate_data.h"
17a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "gin/public/wrapper_info.h"
18c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "gin/wrappable.h"
191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "mojo/bindings/js/drain_data.h"
20a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "mojo/bindings/js/handle.h"
21a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
22a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)namespace mojo {
23a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)namespace js {
24a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
25a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)namespace {
26a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
27c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochMojoResult CloseHandle(gin::Handle<gin::HandleWrapper> handle) {
28c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (!handle->get().is_valid())
29c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    return MOJO_RESULT_INVALID_ARGUMENT;
30c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  handle->Close();
31c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  return MOJO_RESULT_OK;
32c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
33c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
34c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochMojoResult WaitHandle(mojo::Handle handle,
35f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                      MojoHandleSignals signals,
36c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                      MojoDeadline deadline) {
37f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return MojoWait(handle.value(), signals, deadline);
38c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
39c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
40c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochMojoResult WaitMany(
41c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    const std::vector<mojo::Handle>& handles,
42f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const std::vector<MojoHandleSignals>& signals,
43c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    MojoDeadline deadline) {
44f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return mojo::WaitMany(handles, signals, deadline);
45c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
46c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
47a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)gin::Dictionary CreateMessagePipe(const gin::Arguments& args) {
48116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  gin::Dictionary dictionary = gin::Dictionary::CreateEmpty(args.isolate());
49116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  dictionary.Set("result", MOJO_RESULT_INVALID_ARGUMENT);
50116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MojoHandle handle0 = MOJO_HANDLE_INVALID;
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MojoHandle handle1 = MOJO_HANDLE_INVALID;
53116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  MojoResult result = MOJO_RESULT_OK;
54a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
55116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  v8::Handle<v8::Value> options_value = args.PeekNext();
56116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (options_value.IsEmpty() || options_value->IsNull() ||
57116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      options_value->IsUndefined()) {
58116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    result = MojoCreateMessagePipe(NULL, &handle0, &handle1);
59116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  } else if (options_value->IsObject()) {
60116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    gin::Dictionary options_dict(args.isolate(), options_value->ToObject());
61116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    MojoCreateMessagePipeOptions options;
62116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // For future struct_size, we can probably infer that from the presence of
63116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // properties in options_dict. For now, it's always 8.
64116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    options.struct_size = 8;
65116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // Ideally these would be optional. But the interface makes it hard to
66116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // typecheck them then.
67116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (!options_dict.Get("flags", &options.flags)) {
68116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      return dictionary;
69116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    }
70116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
71116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    result = MojoCreateMessagePipe(&options, &handle0, &handle1);
72116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  } else {
73116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      return dictionary;
74116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
75116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
76116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  CHECK_EQ(MOJO_RESULT_OK, result);
77116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
78116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  dictionary.Set("result", result);
79c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  dictionary.Set("handle0", mojo::Handle(handle0));
80c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  dictionary.Set("handle1", mojo::Handle(handle1));
81a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return dictionary;
82a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
83a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
84c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochMojoResult WriteMessage(
85c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    mojo::Handle handle,
86c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    const gin::ArrayBufferView& buffer,
87c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    const std::vector<gin::Handle<gin::HandleWrapper> >& handles,
88c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    MojoWriteMessageFlags flags) {
89c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  std::vector<MojoHandle> raw_handles(handles.size());
90c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  for (size_t i = 0; i < handles.size(); ++i)
91c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    raw_handles[i] = handles[i]->get().value();
92c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  MojoResult rv = MojoWriteMessage(handle.value(),
93a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                          buffer.bytes(),
94a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                          static_cast<uint32_t>(buffer.num_bytes()),
95c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                          raw_handles.empty() ? NULL : &raw_handles[0],
96c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                          static_cast<uint32_t>(raw_handles.size()),
97a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                          flags);
98c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // MojoWriteMessage takes ownership of the handles upon success, so
99c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // release them here.
100c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (rv == MOJO_RESULT_OK) {
101c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    for (size_t i = 0; i < handles.size(); ++i)
102010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      ignore_result(handles[i]->release());
103c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  }
104c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  return rv;
105a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
106a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
10723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)gin::Dictionary ReadMessage(const gin::Arguments& args,
108c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                            mojo::Handle handle,
109a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                            MojoReadMessageFlags flags) {
110a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  uint32_t num_bytes = 0;
111a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  uint32_t num_handles = 0;
112a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  MojoResult result = MojoReadMessage(
113c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      handle.value(), NULL, &num_bytes, NULL, &num_handles, flags);
114a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (result != MOJO_RESULT_RESOURCE_EXHAUSTED) {
115a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    gin::Dictionary dictionary = gin::Dictionary::CreateEmpty(args.isolate());
116a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    dictionary.Set("result", result);
117a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return dictionary;
118a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
119a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
120a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  v8::Handle<v8::ArrayBuffer> array_buffer =
121a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      v8::ArrayBuffer::New(args.isolate(), num_bytes);
122c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  std::vector<mojo::Handle> handles(num_handles);
123a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
124a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  gin::ArrayBuffer buffer;
125a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ConvertFromV8(args.isolate(), array_buffer, &buffer);
126a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  CHECK(buffer.num_bytes() == num_bytes);
127a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
128c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  result = MojoReadMessage(handle.value(),
129a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                           buffer.bytes(),
130a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                           &num_bytes,
131c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                           handles.empty() ? NULL :
132c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                               reinterpret_cast<MojoHandle*>(&handles[0]),
133a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                           &num_handles,
134a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                           flags);
135a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
136a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  CHECK(buffer.num_bytes() == num_bytes);
137a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  CHECK(handles.size() == num_handles);
138a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
139a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  gin::Dictionary dictionary = gin::Dictionary::CreateEmpty(args.isolate());
140a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  dictionary.Set("result", result);
141a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  dictionary.Set("buffer", array_buffer);
142a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  dictionary.Set("handles", handles);
143a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return dictionary;
144a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
145a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
146116680a4aac90f2aa7413d9095a592090648e557Ben Murdochgin::Dictionary CreateDataPipe(const gin::Arguments& args) {
14723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  gin::Dictionary dictionary = gin::Dictionary::CreateEmpty(args.isolate());
14823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  dictionary.Set("result", MOJO_RESULT_INVALID_ARGUMENT);
14923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
15023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  MojoHandle producer_handle = MOJO_HANDLE_INVALID;
15123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  MojoHandle consumer_handle = MOJO_HANDLE_INVALID;
15223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  MojoResult result = MOJO_RESULT_OK;
15323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
154116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  v8::Handle<v8::Value> options_value = args.PeekNext();
155116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (options_value.IsEmpty() || options_value->IsNull() ||
156116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      options_value->IsUndefined()) {
157116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    result = MojoCreateDataPipe(NULL, &producer_handle, &consumer_handle);
158116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  } else if (options_value->IsObject()) {
15923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    gin::Dictionary options_dict(args.isolate(), options_value->ToObject());
16023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    MojoCreateDataPipeOptions options;
16123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    // For future struct_size, we can probably infer that from the presence of
16223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    // properties in options_dict. For now, it's always 16.
16323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    options.struct_size = 16;
16423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    // Ideally these would be optional. But the interface makes it hard to
16523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    // typecheck them then.
16623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    if (!options_dict.Get("flags", &options.flags) ||
16723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        !options_dict.Get("elementNumBytes", &options.element_num_bytes) ||
16823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        !options_dict.Get("capacityNumBytes", &options.capacity_num_bytes)) {
16923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      return dictionary;
17023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    }
17123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
17223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    result = MojoCreateDataPipe(&options, &producer_handle, &consumer_handle);
17323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  } else {
17423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    return dictionary;
17523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  }
17623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
17723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  CHECK_EQ(MOJO_RESULT_OK, result);
17823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
17923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  dictionary.Set("result", result);
180c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  dictionary.Set("producerHandle", mojo::Handle(producer_handle));
181c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  dictionary.Set("consumerHandle", mojo::Handle(consumer_handle));
18223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  return dictionary;
18323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
18423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
18523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)gin::Dictionary WriteData(const gin::Arguments& args,
186c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                          mojo::Handle handle,
18723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                          const gin::ArrayBufferView& buffer,
18823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                          MojoWriteDataFlags flags) {
18923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  uint32_t num_bytes = static_cast<uint32_t>(buffer.num_bytes());
190c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  MojoResult result =
191c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      MojoWriteData(handle.value(), buffer.bytes(), &num_bytes, flags);
19223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  gin::Dictionary dictionary = gin::Dictionary::CreateEmpty(args.isolate());
19323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  dictionary.Set("result", result);
19423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  dictionary.Set("numBytes", num_bytes);
19523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  return dictionary;
19623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
19723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
19823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)gin::Dictionary ReadData(const gin::Arguments& args,
199c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                         mojo::Handle handle,
20023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                         MojoReadDataFlags flags) {
20123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  uint32_t num_bytes = 0;
20223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  MojoResult result = MojoReadData(
203c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      handle.value(), NULL, &num_bytes, MOJO_READ_DATA_FLAG_QUERY);
20423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  if (result != MOJO_RESULT_OK) {
20523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    gin::Dictionary dictionary = gin::Dictionary::CreateEmpty(args.isolate());
20623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    dictionary.Set("result", result);
20723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    return dictionary;
20823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  }
20923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
21023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  v8::Handle<v8::ArrayBuffer> array_buffer =
21123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      v8::ArrayBuffer::New(args.isolate(), num_bytes);
21223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  gin::ArrayBuffer buffer;
21323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  ConvertFromV8(args.isolate(), array_buffer, &buffer);
21423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  CHECK_EQ(num_bytes, buffer.num_bytes());
21523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
216c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  result = MojoReadData(handle.value(), buffer.bytes(), &num_bytes, flags);
21723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  CHECK_EQ(num_bytes, buffer.num_bytes());
21823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
21923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  gin::Dictionary dictionary = gin::Dictionary::CreateEmpty(args.isolate());
22023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  dictionary.Set("result", result);
22123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  dictionary.Set("buffer", array_buffer);
22223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  return dictionary;
22323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
22423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
2251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Asynchronously read all of the data available for the specified data pipe
2261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// consumer handle until the remote handle is closed or an error occurs. A
2271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Promise is returned whose settled value is an object like this:
2281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// {result: core.RESULT_OK, buffer: dataArrayBuffer}. If the read failed,
2291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// then the Promise is rejected, the result will be the actual error code,
2301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// and the buffer will contain whatever was read before the error occurred.
2311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// The drainData data pipe handle argument is closed automatically.
2321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciv8::Handle<v8::Value> DoDrainData(gin::Arguments* args, mojo::Handle handle) {
2341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return (new DrainData(args->isolate(), handle))->GetPromise();
2351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
237a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)gin::WrapperInfo g_wrapper_info = { gin::kEmbedderNativeGin };
238a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
239a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}  // namespace
240a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochconst char Core::kModuleName[] = "mojo/public/js/bindings/core";
242a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)v8::Local<v8::Value> Core::GetModule(v8::Isolate* isolate) {
244a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  gin::PerIsolateData* data = gin::PerIsolateData::From(isolate);
245a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  v8::Local<v8::ObjectTemplate> templ = data->GetObjectTemplate(
246a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      &g_wrapper_info);
247a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
248a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (templ.IsEmpty()) {
249a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)     templ = gin::ObjectTemplateBuilder(isolate)
250c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        // TODO(mpcomplete): Should these just be methods on the JS Handle
251c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        // object?
252c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        .SetMethod("close", CloseHandle)
253c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        .SetMethod("wait", WaitHandle)
254c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        .SetMethod("waitMany", WaitMany)
255a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        .SetMethod("createMessagePipe", CreateMessagePipe)
256a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        .SetMethod("writeMessage", WriteMessage)
257a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        .SetMethod("readMessage", ReadMessage)
25823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        .SetMethod("createDataPipe", CreateDataPipe)
25923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        .SetMethod("writeData", WriteData)
26023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        .SetMethod("readData", ReadData)
2611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        .SetMethod("drainData", DoDrainData)
262a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
263a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        .SetValue("RESULT_OK", MOJO_RESULT_OK)
264a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        .SetValue("RESULT_CANCELLED", MOJO_RESULT_CANCELLED)
265a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        .SetValue("RESULT_UNKNOWN", MOJO_RESULT_UNKNOWN)
266a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        .SetValue("RESULT_INVALID_ARGUMENT", MOJO_RESULT_INVALID_ARGUMENT)
267a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        .SetValue("RESULT_DEADLINE_EXCEEDED", MOJO_RESULT_DEADLINE_EXCEEDED)
268a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        .SetValue("RESULT_NOT_FOUND", MOJO_RESULT_NOT_FOUND)
269a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        .SetValue("RESULT_ALREADY_EXISTS", MOJO_RESULT_ALREADY_EXISTS)
270a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        .SetValue("RESULT_PERMISSION_DENIED", MOJO_RESULT_PERMISSION_DENIED)
271a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        .SetValue("RESULT_RESOURCE_EXHAUSTED", MOJO_RESULT_RESOURCE_EXHAUSTED)
272a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        .SetValue("RESULT_FAILED_PRECONDITION", MOJO_RESULT_FAILED_PRECONDITION)
273a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        .SetValue("RESULT_ABORTED", MOJO_RESULT_ABORTED)
274a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        .SetValue("RESULT_OUT_OF_RANGE", MOJO_RESULT_OUT_OF_RANGE)
275a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        .SetValue("RESULT_UNIMPLEMENTED", MOJO_RESULT_UNIMPLEMENTED)
276a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        .SetValue("RESULT_INTERNAL", MOJO_RESULT_INTERNAL)
277a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        .SetValue("RESULT_UNAVAILABLE", MOJO_RESULT_UNAVAILABLE)
278a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        .SetValue("RESULT_DATA_LOSS", MOJO_RESULT_DATA_LOSS)
2795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        .SetValue("RESULT_BUSY", MOJO_RESULT_BUSY)
2805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        .SetValue("RESULT_SHOULD_WAIT", MOJO_RESULT_SHOULD_WAIT)
281a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
282a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        .SetValue("DEADLINE_INDEFINITE", MOJO_DEADLINE_INDEFINITE)
283a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
284f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        .SetValue("HANDLE_SIGNAL_NONE", MOJO_HANDLE_SIGNAL_NONE)
285f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        .SetValue("HANDLE_SIGNAL_READABLE", MOJO_HANDLE_SIGNAL_READABLE)
286116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        .SetValue("HANDLE_SIGNAL_WRITABLE", MOJO_HANDLE_SIGNAL_WRITABLE)
287116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
288116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        .SetValue("CREATE_MESSAGE_PIPE_OPTIONS_FLAG_NONE",
289116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                  MOJO_CREATE_MESSAGE_PIPE_OPTIONS_FLAG_NONE)
290a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
291a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        .SetValue("WRITE_MESSAGE_FLAG_NONE", MOJO_WRITE_MESSAGE_FLAG_NONE)
292a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
293a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        .SetValue("READ_MESSAGE_FLAG_NONE", MOJO_READ_MESSAGE_FLAG_NONE)
294a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        .SetValue("READ_MESSAGE_FLAG_MAY_DISCARD",
295a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                  MOJO_READ_MESSAGE_FLAG_MAY_DISCARD)
29623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
29723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        .SetValue("CREATE_DATA_PIPE_OPTIONS_FLAG_NONE",
29823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                  MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE)
29923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        .SetValue("CREATE_DATA_PIPE_OPTIONS_FLAG_MAY_DISCARD",
30023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                  MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_MAY_DISCARD)
30123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
30223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        .SetValue("WRITE_DATA_FLAG_NONE", MOJO_WRITE_DATA_FLAG_NONE)
30323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        .SetValue("WRITE_DATA_FLAG_ALL_OR_NONE",
30423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                  MOJO_WRITE_DATA_FLAG_ALL_OR_NONE)
30523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
30623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        .SetValue("READ_DATA_FLAG_NONE", MOJO_READ_DATA_FLAG_NONE)
30723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        .SetValue("READ_DATA_FLAG_ALL_OR_NONE",
30823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                  MOJO_READ_DATA_FLAG_ALL_OR_NONE)
30923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        .SetValue("READ_DATA_FLAG_DISCARD", MOJO_READ_DATA_FLAG_DISCARD)
31023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        .SetValue("READ_DATA_FLAG_QUERY", MOJO_READ_DATA_FLAG_QUERY)
311a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        .Build();
312a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
313a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    data->SetObjectTemplate(&g_wrapper_info, templ);
314a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
315a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
3165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return templ->NewInstance();
317a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
318a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
319a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}  // namespace js
320a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}  // namespace mojo
321