2 * Copyright (c) 2011 The Chromium Authors. All rights reserved.
3 * Use of this source code is governed by a BSD-style license that can be
4 * found in the LICENSE file.
8 // Post-message based test for simple rpc based access to name services.
17 #include <sys/fcntl.h>
22 #include "native_client/src/include/nacl_base.h"
24 #include "ppapi/cpp/instance.h"
25 #include "ppapi/cpp/module.h"
26 #include "ppapi/cpp/var.h"
29 class MyInstance
: public pp::Instance
{
31 explicit MyInstance(PP_Instance instance
);
32 virtual ~MyInstance();
33 virtual void HandleMessage(const pp::Var
& message_data
);
36 DISALLOW_COPY_AND_ASSIGN(MyInstance
);
39 // ---------------------------------------------------------------------------
41 MyInstance::MyInstance(PP_Instance instance
)
42 : pp::Instance(instance
) {
45 MyInstance::~MyInstance() {
48 typedef std::map
<std::string
, std::string
> KeyValueMap
;
50 static void ParseMapEntry(KeyValueMap
* map
,
51 std::string
const& entry
) {
52 std::string::size_type eq
= entry
.find('=');
55 if (std::string::npos
!= eq
) {
56 key
= entry
.substr(0, eq
);
57 val
= entry
.substr(eq
+1);
65 // parse a name1=value1,name2=value2 string into a map, using NRVO. spaces
66 // are significant (!).
68 static KeyValueMap
ParseMap(std::string
const& str_map
) {
70 std::string::size_type s
= 0;
71 std::string::size_type comma
;
73 while (std::string::npos
!= (comma
= str_map
.find(',', s
))) {
74 std::string sub
= str_map
.substr(s
, comma
- s
);
76 ParseMapEntry(&nrvo
, sub
);
78 if (s
!= str_map
.size()) {
79 std::string sub
= str_map
.substr(s
);
80 ParseMapEntry(&nrvo
, sub
);
86 static std::string quotes
[] = {
87 "In the year 1878 I took my degree of Doctor of Medicine...\n",
88 "A merry little surge of electricity piped by automatic alarm...\n",
89 "Squire Trelawney, Dr. Livesey, and the rest of these gentlemen...\n",
90 ("It is a truth universally acknowledged,"
91 " that a single man in possession...\n"),
94 void output_quote(int desc
, size_t ix
) {
95 const char* out
= quotes
[ix
].c_str();
96 size_t len
= strlen(out
);
97 (void) write(desc
, out
, len
); /* assumes no partial writes! */
101 // thread start function -- output asynchronously.
103 /* calling conv */ extern "C" {
104 static void* bg_thread(void* state
) {
105 KeyValueMap
* kvm(reinterpret_cast<KeyValueMap
*>(state
));
107 std::string out
= (*kvm
)["stream"];
108 std::string sleep_str
;
111 if ((*kvm
).find("delay_us") != (*kvm
).end()) {
112 sleep_str
= (*kvm
)["delay_us"];
113 if (sleep_str
.length() > 0) {
114 sleep_us
= strtoul(sleep_str
.c_str(), 0, 0);
117 // Try to check that output works when the event handler thread has
118 // already returned back to JavaScript, as opposed to output
119 // occuring while the plugin is still executing the event handler
120 // and blocking the JavaScript main thread.
124 if (out
== "stdout") {
126 } else if (out
== "stderr") {
129 fprintf(stderr
, "bg_thread: unrecognized output stream %s\n",
136 // HandleMessage gets invoked when postMessage is called on the DOM
137 // element associated with this plugin instance. In this case, if we
138 // are given a string, we'll post a message back to JavaScript with a
139 // reply -- essentially treating this as a string-based RPC.
140 void MyInstance::HandleMessage(const pp::Var
& message
) {
141 std::string msg
= "None";
142 if (message
.is_string()) {
143 msg
= message
.AsString();
144 KeyValueMap
test_arg(ParseMap(msg
));
145 if (test_arg
["thread"] == "fg") {
146 std::string out
= test_arg
["stream"];
147 if (out
== "stdout") {
149 } else if (out
== "stderr") {
152 fprintf(stderr
, "HandleMessage: unrecognized output stream %s\n",
156 /* spawn thread to do output */
160 reinterpret_cast<const pthread_attr_t
*>(NULL
),
162 reinterpret_cast<void *>(new KeyValueMap(test_arg
)));
166 fprintf(stderr
, "HandleMessage: message is not a string\n");
171 // This object is the global object representing this plugin library as long
173 class MyModule
: public pp::Module
{
175 MyModule() : pp::Module() {}
176 virtual ~MyModule() {}
178 // Override CreateInstance to create your customized Instance object.
179 virtual pp::Instance
*CreateInstance(PP_Instance instance
);
181 DISALLOW_COPY_AND_ASSIGN(MyModule
);
184 pp::Instance
*MyModule::CreateInstance(PP_Instance pp_instance
) {
185 return new MyInstance(pp_instance
);
190 // Factory function for your specialization of the Module object.
191 Module
* CreateModule() {
192 return new MyModule();