Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / components / translate / content / renderer / data_file_renderer_cld_data_provider.cc
blobf2af81b3bb40781ac491dde6882fc13c771c0937
1 // Copyright 2014 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.
5 #include "data_file_renderer_cld_data_provider.h"
7 #include "base/basictypes.h"
8 #include "base/files/file.h"
9 #include "base/files/memory_mapped_file.h"
10 #include "base/lazy_instance.h"
11 #include "base/logging.h"
12 #include "components/translate/content/common/data_file_cld_data_provider_messages.h"
13 #include "content/public/renderer/render_view_observer.h"
14 #include "ipc/ipc_message.h"
15 #include "ipc/ipc_message_macros.h"
16 #include "ipc/ipc_platform_file.h"
17 #include "third_party/cld_2/src/public/compact_lang_det.h"
19 namespace {
21 // A struct that contains the pointer to the CLD mmap. Used so that we can
22 // leverage LazyInstance:Leaky to properly scope the lifetime of the mmap.
23 struct CLDMmapWrapper {
24 CLDMmapWrapper() { value = NULL; }
25 base::MemoryMappedFile* value;
27 base::LazyInstance<CLDMmapWrapper>::Leaky g_cld_mmap =
28 LAZY_INSTANCE_INITIALIZER;
30 } // namespace
32 namespace translate {
34 DataFileRendererCldDataProvider::DataFileRendererCldDataProvider(
35 content::RenderViewObserver* render_view_observer)
36 : render_view_observer_(render_view_observer) {
39 DataFileRendererCldDataProvider::~DataFileRendererCldDataProvider() {
42 bool DataFileRendererCldDataProvider::OnMessageReceived(
43 const IPC::Message& message) {
44 bool handled = true;
45 IPC_BEGIN_MESSAGE_MAP(DataFileRendererCldDataProvider, message)
46 IPC_MESSAGE_HANDLER(ChromeViewMsg_CldDataFileAvailable, OnCldDataAvailable)
47 IPC_MESSAGE_UNHANDLED(handled = false)
48 IPC_END_MESSAGE_MAP()
49 return handled;
52 void DataFileRendererCldDataProvider::SendCldDataRequest() {
53 // Else, send the IPC message to the browser process requesting the data...
54 render_view_observer_->Send(new ChromeViewHostMsg_NeedCldDataFile(
55 render_view_observer_->routing_id()));
58 bool DataFileRendererCldDataProvider::IsCldDataAvailable() {
59 // This neatly removes the need for code that depends on the generalized
60 // RendererCldDataProvider to #ifdef on CLD2_DYNAMIC_MODE
61 return CLD2::isDataLoaded(); // ground truth, independent of our state.
64 void DataFileRendererCldDataProvider::SetCldAvailableCallback(
65 base::Callback<void(void)> callback) {
66 cld_available_callback_ = callback;
69 void DataFileRendererCldDataProvider::OnCldDataAvailable(
70 const IPC::PlatformFileForTransit ipc_file_handle,
71 const uint64 data_offset,
72 const uint64 data_length) {
73 LoadCldData(IPC::PlatformFileForTransitToFile(ipc_file_handle),
74 data_offset,
75 data_length);
78 void DataFileRendererCldDataProvider::LoadCldData(base::File file,
79 const uint64 data_offset,
80 const uint64 data_length) {
81 // Terminate immediately if data is already loaded.
82 if (IsCldDataAvailable())
83 return;
85 if (!file.IsValid()) {
86 LOG(ERROR) << "Can't find the CLD data file.";
87 return;
90 // mmap the file
91 g_cld_mmap.Get().value = new base::MemoryMappedFile();
92 bool initialized = g_cld_mmap.Get().value->Initialize(file.Pass());
93 if (!initialized) {
94 LOG(ERROR) << "mmap initialization failed";
95 delete g_cld_mmap.Get().value;
96 g_cld_mmap.Get().value = NULL;
97 return;
100 // Sanity checks
101 uint64 max_int32 = std::numeric_limits<int32>::max();
102 if (data_length + data_offset > g_cld_mmap.Get().value->length() ||
103 data_length > max_int32) { // max signed 32 bit integer
104 LOG(ERROR) << "Illegal mmap config: data_offset=" << data_offset
105 << ", data_length=" << data_length
106 << ", mmap->length()=" << g_cld_mmap.Get().value->length();
107 delete g_cld_mmap.Get().value;
108 g_cld_mmap.Get().value = NULL;
109 return;
112 // Initialize the CLD subsystem... and it's all done!
113 const uint8* data_ptr = g_cld_mmap.Get().value->data() + data_offset;
114 CLD2::loadDataFromRawAddress(data_ptr, data_length);
115 DCHECK(CLD2::isDataLoaded()) << "Failed to load CLD data from mmap";
116 if (!cld_available_callback_.is_null()) {
117 cld_available_callback_.Run();
121 } // namespace translate