15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2011 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/renderer/mhtml_generator.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/view_messages.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/renderer/render_view_impl.h"
9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebCString.h"
107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebPageSerializer.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content {
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MHTMLGenerator::MHTMLGenerator(RenderViewImpl* render_view)
1546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    : RenderViewObserver(render_view) {
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MHTMLGenerator::~MHTMLGenerator() {
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// RenderViewObserver implementation:
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MHTMLGenerator::OnMessageReceived(const IPC::Message& message) {
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool handled = true;
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPC_BEGIN_MESSAGE_MAP(MHTMLGenerator, message)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      IPC_MESSAGE_HANDLER(ViewMsg_SavePageAsMHTML, OnSavePageAsMHTML)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      IPC_MESSAGE_UNHANDLED(handled = false)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPC_END_MESSAGE_MAP()
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return handled;
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MHTMLGenerator::OnSavePageAsMHTML(
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int job_id, IPC::PlatformFileForTransit file_for_transit) {
3346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  file_ = IPC::PlatformFileForTransitToFile(file_for_transit);
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 size = GenerateMHTML();
3546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  file_.Close();
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NotifyBrowser(job_id, size);
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MHTMLGenerator::NotifyBrowser(int job_id, int64 data_size) {
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  render_view()->Send(new ViewHostMsg_SavedPageAsMHTML(job_id, data_size));
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(jcivelli): write the chunks in deferred tasks to give a chance to the
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//                 message loop to process other events.
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int64 MHTMLGenerator::GenerateMHTML() {
46f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  blink::WebCString mhtml =
47f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      blink::WebPageSerializer::serializeToMHTML(render_view()->GetWebView());
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const size_t chunk_size = 1024;
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* data = mhtml.data();
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t total_bytes_written = 0;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (total_bytes_written < mhtml.length()) {
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    size_t copy_size =
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        std::min(mhtml.length() - total_bytes_written, chunk_size);
5446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    int bytes_written = file_.Write(total_bytes_written,
5546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                    data + total_bytes_written, copy_size);
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (bytes_written == -1)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return -1;
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    total_bytes_written += bytes_written;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return total_bytes_written;
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace content
64