summaryrefslogtreecommitdiffstats
path: root/webkit/glue/plugins/plugin_stream.h
blob: f15ea660bf0e9786849a1f3a626ab5bbc8b5ca1c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef WEBKIT_GLUE_PLUGIN_PLUGIN_STREAM_H__
#define WEBKIT_GLUE_PLUGIN_PLUGIN_STREAM_H__

#include <string>
#include <vector>

#include "base/file_path.h"
#include "base/ref_counted.h"
#include "third_party/npapi/bindings/npapi.h"

namespace webkit_glue {
class WebPluginResourceClient;
}

namespace NPAPI {

class PluginInstance;

// Base class for a NPAPI stream.  Tracks basic elements
// of a stream for NPAPI notifications and stream position.
class PluginStream : public base::RefCounted<PluginStream> {
 public:
  // Create a new PluginStream object.  If needNotify is true, then the
  // plugin will be notified when the stream has been fully sent.
  PluginStream(PluginInstance *instance,
               const char *url,
               bool need_notify,
               void *notify_data);

  // In case of a redirect, this can be called to update the url.  But it must
  // be called before Open().
  void UpdateUrl(const char* url);

  // Opens the stream to the Plugin.
  // If the mime-type is not specified, we'll try to find one based on the
  // mime-types table and the extension (if any) in the URL.
  // If the size of the stream is known, use length to set the size.  If
  // not known, set length to 0.
  // The request_is_seekable parameter indicates whether byte range requests
  // can be issued on the stream.
  bool Open(const std::string &mime_type,
            const std::string &headers,
            uint32 length,
            uint32 last_modified,
            bool request_is_seekable);

  // Writes to the stream.
  int Write(const char *buf, const int len, int data_offset);

  // Write the result as a file.
  void WriteAsFile();

  // Notify the plugin that a stream is complete.
  void Notify(NPReason reason);

  // Close the stream.
  virtual bool Close(NPReason reason);

  virtual webkit_glue::WebPluginResourceClient* AsResourceClient() {
    return NULL;
  }

  // Cancels any HTTP requests initiated by the stream.
  virtual void CancelRequest() {}

  const NPStream* stream() const { return &stream_; }

  // setter/getter for the seekable attribute on the stream.
  bool seekable() const { return seekable_stream_; }

  void set_seekable(bool seekable) { seekable_stream_ = seekable; }

  // getters for reading the notification related attributes on the stream.
  bool notify_needed() const { return notify_needed_; }

  void* notify_data() const { return notify_data_; }

 protected:
  friend class base::RefCounted<PluginStream>;

  virtual ~PluginStream();

  PluginInstance* instance() { return instance_.get(); }
  // Check if the stream is open.
  bool open() { return opened_; }

 private:

  // Open a temporary file for this stream.
  // If successful, will set temp_file_name_, temp_file_handle_, and
  // return true.
  bool OpenTempFile();

  // Closes the temporary file if it is open.
  void CloseTempFile();

  // Sends the data to the file. Called From WriteToFile.
  size_t WriteBytes(const char *buf, size_t length);

  // Sends the data to the file if it's open.
  bool WriteToFile(const char *buf, size_t length);

  // Sends the data to the plugin.  If it's not ready, handles buffering it
  // and retrying later.
  bool WriteToPlugin(const char *buf, const int length, const int data_offset);

  // Send the data to the plugin, returning how many bytes it accepted, or -1
  // if an error occurred.
  int TryWriteToPlugin(const char *buf, const int length, const int data_offset);

  // The callback which calls TryWriteToPlugin.
  void OnDelayDelivery();

  // Returns true if the temp file is valid and open for writing.
  bool TempFileIsValid();

 private:
  NPStream                      stream_;
  std::string                   headers_;
  scoped_refptr<PluginInstance> instance_;
  bool                          notify_needed_;
  void *                        notify_data_;
  bool                          close_on_write_data_;
  uint16                        requested_plugin_mode_;
  bool                          opened_;
#if defined(OS_WIN)
  char                          temp_file_name_[MAX_PATH];
  HANDLE                        temp_file_handle_;
#elif defined(OS_POSIX)
  FILE*                         temp_file_;
  FilePath                      temp_file_path_;
#endif
  std::vector<char>             delivery_data_;
  int                           data_offset_;
  bool                          seekable_stream_;
  std::string                   mime_type_;
  DISALLOW_COPY_AND_ASSIGN(PluginStream);
};

} // namespace NPAPI

#endif // WEBKIT_GLUE_PLUGIN_PLUGIN_STREAM_H__