1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5// This example demonstrates how to load content of the page into NaCl module.
6
7#include <cstdio>
8#include <string>
9#include "ppapi/cpp/instance.h"
10#include "ppapi/cpp/module.h"
11#include "ppapi/cpp/url_loader.h"
12#include "ppapi/cpp/var.h"
13
14#include "url_loader_handler.h"
15
16// These are the method names as JavaScript sees them.
17namespace {
18const char* const kLoadUrlMethodId = "getUrl";
19static const char kMessageArgumentSeparator = ':';
20}  // namespace
21
22class URLLoaderInstance : public pp::Instance {
23 public:
24  explicit URLLoaderInstance(PP_Instance instance) : pp::Instance(instance) {}
25  virtual ~URLLoaderInstance() {}
26
27  // Called by the browser to handle the postMessage() call in Javascript.
28  // The message in this case is expected to contain the string 'getUrl'
29  // followed by a ':' separator, then the URL to fetch.  If a valid message
30  // of the form 'getUrl:URL' is received, then start up an asynchronous
31  // download of URL.  In the event that errors occur, this method posts an
32  // error string back to the browser.
33  virtual void HandleMessage(const pp::Var& var_message);
34};
35
36void URLLoaderInstance::HandleMessage(const pp::Var& var_message) {
37  if (!var_message.is_string()) {
38    return;
39  }
40  std::string message = var_message.AsString();
41  if (message.find(kLoadUrlMethodId) == 0) {
42    // The argument to getUrl is everything after the first ':'.
43    size_t sep_pos = message.find_first_of(kMessageArgumentSeparator);
44    if (sep_pos != std::string::npos) {
45      std::string url = message.substr(sep_pos + 1);
46      printf("URLLoaderInstance::HandleMessage('%s', '%s')\n",
47             message.c_str(),
48             url.c_str());
49      fflush(stdout);
50      URLLoaderHandler* handler = URLLoaderHandler::Create(this, url);
51      if (handler != NULL) {
52        // Starts asynchronous download. When download is finished or when an
53        // error occurs, |handler| posts the results back to the browser
54        // vis PostMessage and self-destroys.
55        handler->Start();
56      }
57    }
58  }
59}
60
61class URLLoaderModule : public pp::Module {
62 public:
63  URLLoaderModule() : pp::Module() {}
64  virtual ~URLLoaderModule() {}
65
66  // Create and return a URLLoaderInstance object.
67  virtual pp::Instance* CreateInstance(PP_Instance instance) {
68    return new URLLoaderInstance(instance);
69  }
70};
71
72namespace pp {
73Module* CreateModule() { return new URLLoaderModule(); }
74}  // namespace pp
75