1cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Copyright (c) 2010 The Chromium Authors. All rights reserved.
2cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// found in the LICENSE file.
4cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
5cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#ifndef PDF_DOCUMENT_LOADER_H_
6cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#define PDF_DOCUMENT_LOADER_H_
7cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
8cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include <list>
9cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include <string>
10cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include <vector>
11cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
12cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/basictypes.h"
13cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "pdf/chunk_stream.h"
14cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ppapi/cpp/url_loader.h"
15cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ppapi/utility/completion_callback_factory.h"
16cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
17cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#define kDefaultRequestSize 32768u
18cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
19cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace chrome_pdf {
20cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
21cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)class DocumentLoader {
22cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) public:
23cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  class Client {
24cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  public:
25cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // Gets the pp::Instance object.
26cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    virtual pp::Instance* GetPluginInstance() = 0;
27cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // Creates new URLLoader based on client settings.
28cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    virtual pp::URLLoader CreateURLLoader() = 0;
29cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // Notification called when partial information about document is available.
30cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // Only called for urls that returns full content size and supports byte
31cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // range requests.
32cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    virtual void OnPartialDocumentLoaded() = 0;
33cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // Notification called when all outstanding pending requests are complete.
34cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    virtual void OnPendingRequestComplete() = 0;
35cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // Notification called when new data is available.
36cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    virtual void OnNewDataAvailable() = 0;
37cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // Notification called when document is fully loaded.
38cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    virtual void OnDocumentComplete() = 0;
39cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  };
40cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
41cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  explicit DocumentLoader(Client* client);
42cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual ~DocumentLoader();
43cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
44cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool Init(const pp::URLLoader& loader,
45cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            const std::string& url,
46cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            const std::string& headers);
47cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
48cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Data access interface. Return true is sucessful.
49cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool GetBlock(uint32 position, uint32 size, void* buf) const;
50cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
51cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Data availability interface. Return true data avaialble.
52cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool IsDataAvailable(uint32 position, uint32 size) const;
53cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
54cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Data availability interface. Return true data avaialble.
55cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  void RequestData(uint32 position, uint32 size);
56cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
57cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool IsDocumentComplete() const;
58cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  uint32 document_size() const { return document_size_; }
59cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
60cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Return number of bytes available.
61cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  uint32 GetAvailableData() const;
62cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
63cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Clear pending requests from the queue.
64cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  void ClearPendingRequests();
65cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
66cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool is_partial_document() { return partial_document_; }
67cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
68cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) private:
69cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Called by the completion callback of the document's URLLoader.
70cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  void DidOpen(int32_t result);
71cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Call to read data from the document's URLLoader.
72cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  void ReadMore();
73cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Called by the completion callback of the document's URLLoader.
74cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  void DidRead(int32_t result);
75cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
76cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // If the headers have a byte-range response, writes the start and end
77cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // positions and returns true if at least the start position was parsed.
78cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // The end position will be set to 0 if it was not found or parsed from the
79cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // response.
80cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Returns false if not even a start position could be parsed.
81cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  static bool GetByteRange(const std::string& headers, uint32* start,
82cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                           uint32* end);
83cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
84cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // If the headers have a multi-part response, returns the boundary name.
85cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Otherwise returns an empty string.
86cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  static std::string GetMultiPartBoundary(const std::string& headers);
87cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
88cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Called when we detect that partial document load is possible.
89cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  void LoadPartialDocument();
90cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Called when we have to load full document.
91cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  void LoadFullDocument();
92cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Download pending requests.
93cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  void DownloadPendingRequests();
94cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Called when we complete server request and read all data from it.
95cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  void ReadComplete();
96cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Creates request to download size byte of data data starting from position.
97cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  pp::URLRequestInfo GetRequest(uint32 position, uint32 size) const;
98cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Returns current request size in bytes.
99cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  uint32 GetRequestSize() const;
100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  Client* client_;
102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::string url_;
103cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  pp::URLLoader loader_;
104cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  pp::CompletionCallbackFactory<DocumentLoader> loader_factory_;
105cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ChunkStream chunk_stream_;
106cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool partial_document_;
107cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool request_pending_;
108cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  typedef std::list<std::pair<size_t, size_t> > PendingRequests;
109cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  PendingRequests pending_requests_;
110cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  char buffer_[kDefaultRequestSize];
111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  uint32 current_pos_;
112cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  uint32 current_chunk_size_;
113cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  uint32 current_chunk_read_;
114cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  uint32 document_size_;
115cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool header_request_;
116cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool is_multipart_;
117cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::string multipart_boundary_;
118cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  uint32 requests_count_;
119cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::list<std::vector<unsigned char> > chunk_buffer_;
120cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)};
121cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
122cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}  // namespace chrome_pdf
123cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
124cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#endif  // PDF_DOCUMENT_LOADER_H_
125