summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--base/base.xcodeproj/project.pbxproj2
-rw-r--r--base/file_util.cc21
-rw-r--r--base/file_util.h17
-rw-r--r--chrome/browser/browser.scons1
-rw-r--r--chrome/browser/renderer_host/browser_render_process_host.cc16
-rw-r--r--chrome/browser/spellchecker.cc3
-rw-r--r--chrome/browser/spellchecker.h5
-rw-r--r--chrome/browser/visitedlink_master.cc166
-rw-r--r--chrome/browser/visitedlink_master.h25
-rw-r--r--chrome/browser/visitedlink_perftest.cc8
-rw-r--r--chrome/browser/visitedlink_unittest.cc46
-rw-r--r--chrome/chrome.xcodeproj/project.pbxproj2
-rw-r--r--chrome/common/temp_scaffolding_stubs.h44
13 files changed, 250 insertions, 106 deletions
diff --git a/base/base.xcodeproj/project.pbxproj b/base/base.xcodeproj/project.pbxproj
index e347a84..5c9ab7a 100644
--- a/base/base.xcodeproj/project.pbxproj
+++ b/base/base.xcodeproj/project.pbxproj
@@ -644,6 +644,7 @@
ABF68B280EB0F93100E72835 /* field_trial.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = field_trial.cc; sourceTree = "<group>"; };
B290BFCBD30E45A63758BFC7 /* waitable_event_posix.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = waitable_event_posix.cc; sourceTree = "<group>"; };
B52C916B0E9428F500208D01 /* clipboard_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = clipboard_unittest.cc; sourceTree = "<group>"; };
+ B57D788E0F26983200685566 /* scoped_file.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = scoped_file.h; sourceTree = "<group>"; };
B57E4D770E9C26340090055D /* idletimer_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = idletimer_unittest.cc; sourceTree = "<group>"; };
B5A8618D0EC1257900B332C2 /* clipboard.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = clipboard.cc; sourceTree = "<group>"; };
B5D544AA0EAFB7E000272A1C /* sys_string_conversions_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sys_string_conversions_unittest.cc; sourceTree = "<group>"; };
@@ -1002,6 +1003,7 @@
7B5AD60D0D9DD8050012BCF1 /* scoped_cftyperef.h */,
B5E8F6CB0EBFB38E008DD1E9 /* scoped_clipboard_writer.cc */,
B5E8F6CA0EBFB38E008DD1E9 /* scoped_clipboard_writer.h */,
+ B57D788E0F26983200685566 /* scoped_file.h */,
7BA35DD10E8C0D5F0023C8B9 /* scoped_nsautorelease_pool.h */,
7BA35DD20E8C0D5F0023C8B9 /* scoped_nsautorelease_pool.mm */,
825403610D92D27C0006B936 /* scoped_ptr.h */,
diff --git a/base/file_util.cc b/base/file_util.cc
index 078e3afa..8ecb1cc 100644
--- a/base/file_util.cc
+++ b/base/file_util.cc
@@ -4,6 +4,9 @@
#include "base/file_util.h"
+#if defined(OS_WIN)
+#include <io.h>
+#endif
#include <stdio.h>
#include <fstream>
@@ -276,6 +279,24 @@ bool CloseFile(FILE* file) {
return fclose(file) == 0;
}
+bool TruncateFile(FILE* file) {
+ if (file == NULL)
+ return false;
+ long current_offset = ftell(file);
+ if (current_offset == -1)
+ return false;
+#if defined(OS_WIN)
+ int fd = _fileno(file);
+ if (_chsize(fd, current_offset) != 0)
+ return false;
+#else
+ int fd = fileno(file);
+ if (ftruncate(fd, current_offset) != 0)
+ return false;
+#endif
+ return true;
+}
+
bool ContainsPath(const FilePath &parent, const FilePath& child) {
FilePath abs_parent = FilePath(parent);
FilePath abs_child = FilePath(child);
diff --git a/base/file_util.h b/base/file_util.h
index 4154856..c546b9a 100644
--- a/base/file_util.h
+++ b/base/file_util.h
@@ -24,6 +24,7 @@
#include <vector>
#include "base/basictypes.h"
+#include "base/scoped_ptr.h"
#include "base/file_path.h"
namespace file_util {
@@ -318,6 +319,10 @@ FILE* OpenFile(const std::wstring& filename, const char* mode);
// Closes file opened by OpenFile. Returns true on success.
bool CloseFile(FILE* file);
+// Truncates an open file to end at the location of the current file pointer.
+// This is a cross-platform analog to Windows' SetEndOfFile() function.
+bool TruncateFile(FILE* file);
+
// Reads the given number of bytes from the file into the buffer. Returns
// the number of read bytes, or -1 on error.
int ReadFile(const std::wstring& filename, char* data, int size);
@@ -336,6 +341,18 @@ bool SetCurrentDirectory(const FilePath& path);
// Deprecated temporary compatibility function.
bool SetCurrentDirectory(const std::wstring& current_directory);
+// A class to handle auto-closing of FILE*'s.
+class ScopedFILEClose {
+ public:
+ inline void operator()(FILE* x) const {
+ if (x) {
+ fclose(x);
+ }
+ }
+};
+
+typedef scoped_ptr_malloc<FILE, ScopedFILEClose> ScopedFILE;
+
// A class for enumerating the files in a provided path. The order of the
// results is not guaranteed.
//
diff --git a/chrome/browser/browser.scons b/chrome/browser/browser.scons
index 225d6fa..081e840 100644
--- a/chrome/browser/browser.scons
+++ b/chrome/browser/browser.scons
@@ -819,7 +819,6 @@ if not env.Bit('windows'):
'toolbar_model.cc',
'user_data_manager.cc',
'views/download_tab_view.cc',
- 'visitedlink_master.cc',
'web_app.cc',
'web_app_icon_manager.cc',
'web_app_launcher.cc',
diff --git a/chrome/browser/renderer_host/browser_render_process_host.cc b/chrome/browser/renderer_host/browser_render_process_host.cc
index 823a063..c8b8e6e 100644
--- a/chrome/browser/renderer_host/browser_render_process_host.cc
+++ b/chrome/browser/renderer_host/browser_render_process_host.cc
@@ -27,12 +27,22 @@
#include "chrome/browser/browser_process.h"
#include "chrome/browser/cache_manager_host.h"
#include "chrome/browser/extensions/user_script_master.h"
+#if defined(OS_WIN)
#include "chrome/browser/history/history.h"
+#else
+// TODO(port): remove scaffolding, use history.h for both POSIX and WIN.
+#include "chrome/common/temp_scaffolding_stubs.h"
+#endif // !defined(OS_WIN)
+
#include "chrome/browser/plugin_service.h"
#include "chrome/browser/renderer_host/render_widget_helper.h"
#include "chrome/browser/renderer_host/renderer_security_policy.h"
#include "chrome/browser/resource_message_filter.h"
+#if defined(OS_MACOSX)
+// TODO(port): Enable when we finish porting spellchecker to os x.
+#else
#include "chrome/browser/spellchecker.h"
+#endif // !defined(OS_WIN)
#include "chrome/browser/visitedlink_master.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
@@ -470,11 +480,17 @@ void BrowserRenderProcessHost::WidgetHidden() {
}
void BrowserRenderProcessHost::AddWord(const std::wstring& word) {
+#if defined(OS_MACOSX)
+ // TODO(port): reimplement when we get the spell checker up and running on
+ // OS X.
+ NOTIMPLEMENTED();
+#else
base::Thread* io_thread = g_browser_process->io_thread();
if (profile()->GetSpellChecker()) {
io_thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(
profile()->GetSpellChecker(), &SpellChecker::AddWord, word));
}
+#endif // !defined(OS_MACOSX)
}
base::ProcessHandle BrowserRenderProcessHost::GetRendererProcessHandle() {
diff --git a/chrome/browser/spellchecker.cc b/chrome/browser/spellchecker.cc
index 4269f70..11147b9 100644
--- a/chrome/browser/spellchecker.cc
+++ b/chrome/browser/spellchecker.cc
@@ -14,7 +14,10 @@
#include "chrome/app/locales/locale_settings.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/net/url_fetcher.h"
+#if defined(OS_WIN)
+// TODO(port): remove scaffolding, use profile.h for both POSIX and WIN.
#include "chrome/browser/profile.h"
+#endif
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_counters.h"
#include "chrome/common/chrome_paths.h"
diff --git a/chrome/browser/spellchecker.h b/chrome/browser/spellchecker.h
index 1e97605..e4a3a18 100644
--- a/chrome/browser/spellchecker.h
+++ b/chrome/browser/spellchecker.h
@@ -9,7 +9,12 @@
#include "base/string_util.h"
#include "chrome/browser/browser_process.h"
+#if defined(OS_WIN)
#include "chrome/browser/profile.h"
+#else
+// TODO(port): remove scaffolding, use profile.h for both POSIX and WIN.
+#include "chrome/common/temp_scaffolding_stubs.h"
+#endif
#include "chrome/browser/spellcheck_worditerator.h"
#include "chrome/common/l10n_util.h"
#include "chrome/common/pref_names.h"
diff --git a/chrome/browser/visitedlink_master.cc b/chrome/browser/visitedlink_master.cc
index 22a9638..85470cc 100644
--- a/chrome/browser/visitedlink_master.cc
+++ b/chrome/browser/visitedlink_master.cc
@@ -4,20 +4,40 @@
#include "chrome/browser/visitedlink_master.h"
+#if defined(OS_WIN)
#include <windows.h>
+#include <io.h>
#include <shlobj.h>
+#endif // defined(OS_WIN)
+#include <stdio.h>
+
#include <algorithm>
+#include "base/file_util.h"
#include "base/logging.h"
#include "base/message_loop.h"
#include "base/path_service.h"
+#include "base/process_util.h"
#include "base/rand_util.h"
#include "base/stack_container.h"
#include "base/string_util.h"
+#include "base/thread.h"
#include "chrome/browser/browser_process.h"
+#if defined(OS_WIN)
#include "chrome/browser/history/history.h"
#include "chrome/browser/profile.h"
+#else
+// TODO(port): We should be using history.h & profile.h, remove scaffolding
+// when those are ported.
+#include "chrome/common/temp_scaffolding_stubs.h"
+#endif // !defined(OS_WIN)
+#if defined(OS_WIN)
#include "chrome/common/win_util.h"
+#endif
+
+using file_util::ScopedFILE;
+using file_util::OpenFile;
+using file_util::TruncateFile;
const int32 VisitedLinkMaster::kFileHeaderSignatureOffset = 0;
const int32 VisitedLinkMaster::kFileHeaderVersionOffset = 4;
@@ -36,7 +56,7 @@ const size_t VisitedLinkMaster::kFileHeaderSize =
// table in NewTableSizeForCount (prime number).
const unsigned VisitedLinkMaster::kDefaultTableSize = 16381;
-const int32 VisitedLinkMaster::kBigDeleteThreshold = 64;
+const size_t VisitedLinkMaster::kBigDeleteThreshold = 64;
namespace {
@@ -48,43 +68,42 @@ void GenerateSalt(uint8 salt[LINK_SALT_LENGTH]) {
uint64 randval = base::RandUint64();
memcpy(salt, &randval, 8);
}
+
// AsyncWriter ----------------------------------------------------------------
// This task executes on a background thread and executes a write. This
// prevents us from blocking the UI thread doing I/O.
class AsyncWriter : public Task {
public:
- AsyncWriter(HANDLE hfile, int32 offset, const void* data, int32 data_len)
- : hfile_(hfile),
+ AsyncWriter(FILE* file, int32 offset, const void* data, size_t data_len)
+ : file_(file),
offset_(offset) {
data_->resize(data_len);
memcpy(&*data_->begin(), data, data_len);
}
virtual void Run() {
- WriteToFile(hfile_, offset_,
+ WriteToFile(file_, offset_,
&*data_->begin(), static_cast<int32>(data_->size()));
}
// Exposed as a static so it can be called directly from the Master to
// reduce the number of platform-specific I/O sites we have. Returns true if
// the write was complete.
- static bool WriteToFile(HANDLE hfile,
- int32 offset,
+ static bool WriteToFile(FILE* file,
+ off_t offset,
const void* data,
- int32 data_len) {
- if (SetFilePointer(hfile, offset, NULL, FILE_BEGIN) ==
- INVALID_SET_FILE_POINTER)
+ size_t data_len) {
+ if (fseek(file, offset, SEEK_SET) != 0)
return false; // Don't write to an invalid part of the file.
- DWORD num_written;
- return WriteFile(hfile, data, data_len, &num_written, NULL) &&
- (num_written == data_len);
+ size_t num_written = fwrite(data, 1, data_len, file);
+ return num_written == data_len;
}
private:
// The data to write and where to write it.
- HANDLE hfile_;
+ FILE* file_;
int32 offset_; // Offset from the beginning of the file.
// Most writes are just a single fingerprint, so we reserve that much in this
@@ -98,14 +117,14 @@ class AsyncWriter : public Task {
// same thread as the writing to keep things synchronized.
class AsyncSetEndOfFile : public Task {
public:
- explicit AsyncSetEndOfFile(HANDLE hfile) : hfile_(hfile) {}
+ explicit AsyncSetEndOfFile(FILE* file) : file_(file) {}
virtual void Run() {
- SetEndOfFile(hfile_);
+ TruncateFile(file_);
}
private:
- HANDLE hfile_;
+ FILE* file_;
DISALLOW_EVIL_CONSTRUCTORS(AsyncSetEndOfFile);
};
@@ -113,14 +132,14 @@ class AsyncSetEndOfFile : public Task {
// the writing to keep things synchronized.
class AsyncCloseHandle : public Task {
public:
- explicit AsyncCloseHandle(HANDLE hfile) : hfile_(hfile) {}
+ explicit AsyncCloseHandle(FILE* file) : file_(file) {}
virtual void Run() {
- CloseHandle(hfile_);
+ fclose(file_);
}
private:
- HANDLE hfile_;
+ FILE* file_;
DISALLOW_EVIL_CONSTRUCTORS(AsyncCloseHandle);
};
@@ -194,11 +213,11 @@ VisitedLinkMaster::VisitedLinkMaster(base::Thread* file_thread,
PostNewTableEvent* poster,
HistoryService* history_service,
bool suppress_rebuild,
- const std::wstring& filename,
+ const FilePath& filename,
int32 default_table_size) {
InitMembers(file_thread, poster, NULL);
- database_name_override_.assign(filename);
+ database_name_override_ = filename;
table_size_override_ = default_table_size;
history_service_override_ = history_service;
suppress_rebuild_ = suppress_rebuild;
@@ -248,7 +267,7 @@ std::wstring VisitedLinkMaster::GetSharedMemoryName() const {
profile_id = profile_->GetID().c_str();
return StringPrintf(L"GVisitedLinks_%lu_%lu_%ls",
- GetCurrentProcessId(), shared_memory_serial_,
+ base::GetCurrentProcId(), shared_memory_serial_,
profile_id.c_str());
}
@@ -512,19 +531,19 @@ bool VisitedLinkMaster::WriteFullTable() {
// We should pick up the most common types of these failures when we notice
// that the file size is different when we load it back in, and then we will
// regenerate the table.
- win_util::ScopedHandle hfile_closer; // Valid only when not open already.
- HANDLE hfile; // Always valid.
+ ScopedFILE file_closer; // Valid only when not open already.
+ FILE* file; // Always valid.
if (file_) {
- hfile = file_;
+ file = file_;
} else {
- std::wstring filename;
+ FilePath filename;
GetDatabaseFileName(&filename);
- hfile_closer.Set(
- CreateFile(filename.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL,
- CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL));
- if (!hfile_closer.IsValid())
+ file_closer.reset(OpenFile(filename, "wb+"));
+ if (!file_closer.get()) {
+ DLOG(ERROR) << "Failed to open file " << filename.value();
return false;
- hfile = hfile_closer;
+ }
+ file = file_closer.get();
}
// Write the new header.
@@ -533,54 +552,54 @@ bool VisitedLinkMaster::WriteFullTable() {
header[1] = kFileCurrentVersion;
header[2] = table_length_;
header[3] = used_items_;
- WriteToFile(hfile, 0, header, sizeof(header));
- WriteToFile(hfile, sizeof(header), salt_, LINK_SALT_LENGTH);
+ WriteToFile(file, 0, header, sizeof(header));
+ WriteToFile(file, sizeof(header), salt_, LINK_SALT_LENGTH);
// Write the hash data.
- WriteToFile(hfile, kFileHeaderSize,
+ WriteToFile(file, kFileHeaderSize,
hash_table_, table_length_ * sizeof(Fingerprint));
// The hash table may have shrunk, so make sure this is the end.
if (file_thread_) {
- AsyncSetEndOfFile* setter = new AsyncSetEndOfFile(hfile);
+ AsyncSetEndOfFile* setter = new AsyncSetEndOfFile(file);
file_thread_->PostTask(FROM_HERE, setter);
} else {
- SetEndOfFile(hfile);
+ TruncateFile(file);
}
// Keep the file open so we can dynamically write changes to it. When the
- // file was alrady open, the hfile_closer is NULL, and file_ is already good.
- if (hfile_closer.IsValid())
- file_ = hfile_closer.Take();
+ // file was already open, the file_closer is NULL, and file_ is already good.
+ if (file_closer.get())
+ file_ = file_closer.release();
return true;
}
bool VisitedLinkMaster::InitFromFile() {
DCHECK(file_ == NULL);
- std::wstring filename;
+ FilePath filename;
GetDatabaseFileName(&filename);
- win_util::ScopedHandle hfile(
- CreateFile(filename.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL,
- OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL));
- if (!hfile.IsValid())
+ ScopedFILE file_closer(OpenFile(filename, "rb+"));
+ if (!file_closer.get()) {
+ DLOG(ERROR) << "Failed to open file " << filename.value();
return false;
+ }
int32 num_entries, used_count;
- if (!ReadFileHeader(hfile, &num_entries, &used_count, salt_))
+ if (!ReadFileHeader(file_closer.get(), &num_entries, &used_count, salt_))
return false; // Header isn't valid.
// Allocate and read the table.
if (!CreateURLTable(num_entries, false))
return false;
- if (!ReadFromFile(hfile, kFileHeaderSize,
+ if (!ReadFromFile(file_closer.get(), kFileHeaderSize,
hash_table_, num_entries * sizeof(Fingerprint))) {
FreeURLTable();
return false;
}
used_items_ = used_count;
- file_ = hfile.Take();
+ file_ = file_closer.release();
return true;
}
@@ -609,20 +628,27 @@ bool VisitedLinkMaster::InitFromScratch(bool suppress_rebuild) {
return RebuildTableFromHistory();
}
-bool VisitedLinkMaster::ReadFileHeader(HANDLE hfile,
+bool VisitedLinkMaster::ReadFileHeader(FILE* file,
int32* num_entries,
int32* used_count,
uint8 salt[LINK_SALT_LENGTH]) {
- int32 file_size = GetFileSize(hfile, NULL);
+ // Get file size.
+ // Note that there is no need to seek back to the original location in the
+ // file since ReadFromFile() [which is the next call accessing the file]
+ // seeks before reading.
+ if (fseek(file, 0, SEEK_END) == -1)
+ return false;
+ size_t file_size = ftell(file);
+
if (file_size <= kFileHeaderSize)
return false;
uint8 header[kFileHeaderSize];
- if (!ReadFromFile(hfile, 0, &header, kFileHeaderSize))
+ if (!ReadFromFile(file, 0, &header, kFileHeaderSize))
return false;
// Verify the signature.
- uint32 signature;
+ int32 signature;
memcpy(&signature, &header[kFileHeaderSignatureOffset], sizeof(signature));
if (signature != kFileSignature)
return false;
@@ -652,7 +678,7 @@ bool VisitedLinkMaster::ReadFileHeader(HANDLE hfile,
return true;
}
-bool VisitedLinkMaster::GetDatabaseFileName(std::wstring* filename) {
+bool VisitedLinkMaster::GetDatabaseFileName(FilePath* filename) {
if (!database_name_override_.empty()) {
// use this filename, the directory must exist
*filename = database_name_override_;
@@ -662,8 +688,8 @@ bool VisitedLinkMaster::GetDatabaseFileName(std::wstring* filename) {
if (!profile_ || profile_->GetPath().empty())
return false;
- *filename = profile_->GetPath();
- filename->append(L"\\Visited Links");
+ FilePath profile_dir = FilePath::FromWStringHack(profile_->GetPath());
+ *filename = profile_dir.Append(FILE_PATH_LITERAL("Visited Links"));
return true;
}
@@ -735,7 +761,7 @@ void VisitedLinkMaster::FreeURLTable() {
AsyncCloseHandle* closer = new AsyncCloseHandle(file_);
file_thread_->PostTask(FROM_HERE, closer);
} else {
- CloseHandle(file_);
+ fclose(file_);
}
}
}
@@ -752,7 +778,8 @@ bool VisitedLinkMaster::ResizeTableIfNecessary() {
float load = ComputeTableLoad();
if (load < max_table_load &&
- (table_length_ <= kDefaultTableSize || load > min_table_load))
+ (table_length_ <= static_cast<float>(kDefaultTableSize) ||
+ load > min_table_load))
return false;
// Table needs to grow or shrink.
@@ -823,7 +850,7 @@ uint32 VisitedLinkMaster::NewTableSizeForCount(int32 item_count) const {
int desired = item_count * 3;
// Find the closest prime.
- for (int i = 0; i < arraysize(table_sizes); i ++) {
+ for (size_t i = 0; i < arraysize(table_sizes); i ++) {
if (table_sizes[i] > desired)
return table_sizes[i];
}
@@ -908,8 +935,8 @@ void VisitedLinkMaster::OnTableRebuildComplete(
}
}
-void VisitedLinkMaster::WriteToFile(HANDLE hfile,
- int32 offset,
+void VisitedLinkMaster::WriteToFile(FILE* file,
+ off_t offset,
void* data,
int32 data_size) {
#ifndef NDEBUG
@@ -918,12 +945,12 @@ void VisitedLinkMaster::WriteToFile(HANDLE hfile,
if (file_thread_) {
// Send the write to the other thread for execution to avoid blocking.
- AsyncWriter* writer = new AsyncWriter(hfile, offset, data, data_size);
+ AsyncWriter* writer = new AsyncWriter(file, offset, data, data_size);
file_thread_->PostTask(FROM_HERE, writer);
} else {
// When there is no I/O thread, we are probably running in unit test mode,
// just do the write synchronously.
- AsyncWriter::WriteToFile(hfile, offset, data, data_size);
+ AsyncWriter::WriteToFile(file, offset, data, data_size);
}
}
@@ -949,21 +976,20 @@ void VisitedLinkMaster::WriteHashRangeToFile(Hash first_hash, Hash last_hash) {
}
}
-bool VisitedLinkMaster::ReadFromFile(HANDLE hfile,
- int32 offset,
+bool VisitedLinkMaster::ReadFromFile(FILE* file,
+ off_t offset,
void* data,
- int32 data_size) {
+ size_t data_size) {
#ifndef NDEBUG
// Since this function is synchronous, we require that no asynchronous
// operations could possibly be pending.
DCHECK(!posted_asynchronous_operation_);
#endif
- SetFilePointer(hfile, offset, NULL, FILE_BEGIN);
+ fseek(file, offset, SEEK_SET);
- DWORD num_read;
- return ReadFile(hfile, data, data_size, &num_read, NULL) &&
- num_read == data_size;
+ size_t num_read = fread(data, 1, data_size, file);
+ return num_read == data_size;
}
// VisitedLinkTableBuilder ----------------------------------------------------
@@ -972,8 +998,8 @@ VisitedLinkMaster::TableBuilder::TableBuilder(
VisitedLinkMaster* master,
const uint8 salt[LINK_SALT_LENGTH])
: master_(master),
- success_(true),
- main_message_loop_(MessageLoop::current()) {
+ main_message_loop_(MessageLoop::current()),
+ success_(true) {
fingerprints_.reserve(4096);
memcpy(salt_, salt, sizeof(salt));
}
diff --git a/chrome/browser/visitedlink_master.h b/chrome/browser/visitedlink_master.h
index ac99634..c68e4c7 100644
--- a/chrome/browser/visitedlink_master.h
+++ b/chrome/browser/visitedlink_master.h
@@ -5,13 +5,22 @@
#ifndef CHROME_BROWSER_VISITEDLINK_MASTER_H__
#define CHROME_BROWSER_VISITEDLINK_MASTER_H__
+#if defined(OS_WIN)
+#include <windows.h>
+#endif
#include <set>
#include <string>
#include <vector>
+#include "base/file_path.h"
#include "base/ref_counted.h"
#include "base/shared_memory.h"
+#if defined(OS_WIN)
#include "chrome/browser/history/history.h"
+#else
+// TODO(port): remove scaffolding, use history.h for both POSIX and WIN.
+#include "chrome/common/temp_scaffolding_stubs.h"
+#endif // !defined(OS_WIN)
#include "chrome/common/visitedlink_common.h"
#include "testing/gtest/include/gtest/gtest_prod.h"
@@ -53,7 +62,7 @@ class VisitedLinkMaster : public VisitedLinkCommon {
PostNewTableEvent* poster,
HistoryService* history_service,
bool suppress_rebuild,
- const std::wstring& filename,
+ const FilePath& filename,
int32 default_table_size);
virtual ~VisitedLinkMaster();
@@ -141,7 +150,7 @@ class VisitedLinkMaster : public VisitedLinkCommon {
// When the user is deleting a boatload of URLs, we don't really want to do
// individual writes for each of them. When the count exceeds this threshold,
// we will write the whole table to disk at once instead of individual items.
- static const int32 kBigDeleteThreshold;
+ static const size_t kBigDeleteThreshold;
// Backend for the constructors initializing the members.
void InitMembers(base::Thread* file_thread,
@@ -171,15 +180,15 @@ class VisitedLinkMaster : public VisitedLinkCommon {
// Returns true on success and places the size of the table in num_entries
// and the number of nonzero fingerprints in used_count. This will fail if
// the version of the file is not the current version of the database.
- bool ReadFileHeader(HANDLE hfile, int32* num_entries, int32* used_count,
+ bool ReadFileHeader(FILE* hfile, int32* num_entries, int32* used_count,
uint8 salt[LINK_SALT_LENGTH]);
// Fills *filename with the name of the link database filename
- bool GetDatabaseFileName(std::wstring* filename);
+ bool GetDatabaseFileName(FilePath* filename);
// Wrapper around Window's WriteFile using asynchronous I/O. This will proxy
// the write to a background thread.
- void WriteToFile(HANDLE hfile, int32 offset, void* data, int32 data_size);
+ void WriteToFile(FILE* hfile, off_t offset, void* data, int32 data_size);
// Helper function to schedule and asynchronous write of the used count to
// disk (this is a common operation).
@@ -192,7 +201,7 @@ class VisitedLinkMaster : public VisitedLinkCommon {
// Synchronous read from the file. Assumes there are no pending asynchronous
// I/O functions. Returns true if the entire buffer was successfully filled.
- bool ReadFromFile(HANDLE hfile, int32 offset, void* data, int32 data_size);
+ bool ReadFromFile(FILE* hfile, off_t offset, void* data, size_t data_size);
// General table handling
// ----------------------
@@ -326,7 +335,7 @@ class VisitedLinkMaster : public VisitedLinkCommon {
// The currently open file with the table in it. This may be NULL if we're
// rebuilding and haven't written a new version yet. Writing to the file may
// be safely ignored in this case.
- HANDLE file_;
+ FILE* file_;
// Shared memory consists of a SharedHeader followed by the table.
base::SharedMemory *shared_memory_;
@@ -347,7 +356,7 @@ class VisitedLinkMaster : public VisitedLinkCommon {
// in release builds that give "regular" behavior.
// Overridden database file name for testing
- std::wstring database_name_override_;
+ FilePath database_name_override_;
// When nonzero, overrides the table size for new databases for testing
int32 table_size_override_;
diff --git a/chrome/browser/visitedlink_perftest.cc b/chrome/browser/visitedlink_perftest.cc
index fc412d4..8184824 100644
--- a/chrome/browser/visitedlink_perftest.cc
+++ b/chrome/browser/visitedlink_perftest.cc
@@ -81,7 +81,7 @@ class VisitedLink : public testing::Test {
TEST_F(VisitedLink, TestAddAndQuery) {
// init
VisitedLinkMaster master(NULL, DummyBroadcastNewTableEvent, NULL, true,
- db_name_, 0);
+ FilePath(db_name_), 0);
ASSERT_TRUE(master.Init());
PerfTimeLogger timer("Visited_link_add_and_query");
@@ -112,7 +112,7 @@ TEST_F(VisitedLink, TestLoad) {
PerfTimeLogger table_initialization_timer("Table_initialization");
VisitedLinkMaster master(NULL, DummyBroadcastNewTableEvent, NULL, true,
- db_name_, 0);
+ FilePath(db_name_), 0);
// time init with empty table
PerfTimeLogger initTimer("Empty_visited_link_init");
@@ -152,7 +152,7 @@ TEST_F(VisitedLink, TestLoad) {
PerfTimer cold_timer;
VisitedLinkMaster master(NULL, DummyBroadcastNewTableEvent, NULL, true,
- db_name_, 0);
+ FilePath(db_name_), 0);
bool success = master.Init();
TimeDelta elapsed = cold_timer.Elapsed();
ASSERT_TRUE(success);
@@ -165,7 +165,7 @@ TEST_F(VisitedLink, TestLoad) {
PerfTimer hot_timer;
VisitedLinkMaster master(NULL, DummyBroadcastNewTableEvent, NULL, true,
- db_name_, 0);
+ FilePath(db_name_), 0);
bool success = master.Init();
TimeDelta elapsed = hot_timer.Elapsed();
ASSERT_TRUE(success);
diff --git a/chrome/browser/visitedlink_unittest.cc b/chrome/browser/visitedlink_unittest.cc
index 86c2a24..2dac97f 100644
--- a/chrome/browser/visitedlink_unittest.cc
+++ b/chrome/browser/visitedlink_unittest.cc
@@ -9,6 +9,7 @@
#include "base/message_loop.h"
#include "base/file_util.h"
#include "base/path_service.h"
+#include "base/process_util.h"
#include "base/shared_memory.h"
#include "base/string_util.h"
#include "chrome/browser/visitedlink_master.h"
@@ -28,28 +29,28 @@ GURL TestURL(int i) {
return GURL(StringPrintf("%s%d", g_test_prefix, i));
}
-// when testing in single-threaded mode
-VisitedLinkMaster* g_master = NULL;
std::vector<VisitedLinkSlave*> g_slaves;
VisitedLinkMaster::PostNewTableEvent SynchronousBroadcastNewTableEvent;
void SynchronousBroadcastNewTableEvent(base::SharedMemory* table) {
if (table) {
for (std::vector<VisitedLinkSlave>::size_type i = 0;
- i < (int)g_slaves.size(); i++) {
+ i < g_slaves.size(); i++) {
base::SharedMemoryHandle new_handle = NULL;
- table->ShareToProcess(GetCurrentProcess(), &new_handle);
+ table->ShareToProcess(base::GetCurrentProcessHandle(), &new_handle);
g_slaves[i]->Init(new_handle);
}
}
}
+} // namespace
+
class VisitedLinkTest : public testing::Test {
protected:
// Initialize the history system. This should be called before InitVisited().
bool InitHistory() {
history_service_ = new HistoryService;
- return history_service_->Init(history_dir_, NULL);
+ return history_service_->Init(history_dir_.ToWStringHack(), NULL);
}
// Initializes the visited link objects. Pass in the size that you want a
@@ -103,7 +104,7 @@ class VisitedLinkTest : public testing::Test {
// Create a slave database.
VisitedLinkSlave slave;
base::SharedMemoryHandle new_handle = NULL;
- master_->ShareToProcess(GetCurrentProcess(), &new_handle);
+ master_->ShareToProcess(base::GetCurrentProcessHandle(), &new_handle);
bool success = slave.Init(new_handle);
ASSERT_TRUE(success);
g_slaves.push_back(&slave);
@@ -132,12 +133,11 @@ class VisitedLinkTest : public testing::Test {
// testing::Test
virtual void SetUp() {
PathService::Get(base::DIR_TEMP, &history_dir_);
- file_util::AppendToPath(&history_dir_, L"VisitedLinkTest");
+ history_dir_ = history_dir_.Append(FILE_PATH_LITERAL("VisitedLinkTest"));
file_util::Delete(history_dir_, true);
file_util::CreateDirectory(history_dir_);
- visited_file_ = history_dir_;
- file_util::AppendToPath(&visited_file_, L"VisitedLinks");
+ visited_file_ = history_dir_.Append(FILE_PATH_LITERAL("VisitedLinks"));
}
virtual void TearDown() {
@@ -148,15 +148,13 @@ class VisitedLinkTest : public testing::Test {
MessageLoop message_loop_;
// Filenames for the services;
- std::wstring history_dir_;
- std::wstring visited_file_;
+ FilePath history_dir_;
+ FilePath visited_file_;
scoped_ptr<VisitedLinkMaster> master_;
scoped_refptr<HistoryService> history_service_;
};
-} // namespace
-
// This test creates and reads some databases to make sure the data is
// preserved throughout those operations.
TEST_F(VisitedLinkTest, DatabaseIO) {
@@ -178,11 +176,11 @@ TEST_F(VisitedLinkTest, Delete) {
// Add a cluster from 14-17 wrapping around to 0. These will all hash to the
// same value.
- const int kFingerprint0 = kInitialSize * 0 + 14;
- const int kFingerprint1 = kInitialSize * 1 + 14;
- const int kFingerprint2 = kInitialSize * 2 + 14;
- const int kFingerprint3 = kInitialSize * 3 + 14;
- const int kFingerprint4 = kInitialSize * 4 + 14;
+ const VisitedLinkCommon::Fingerprint kFingerprint0 = kInitialSize * 0 + 14;
+ const VisitedLinkCommon::Fingerprint kFingerprint1 = kInitialSize * 1 + 14;
+ const VisitedLinkCommon::Fingerprint kFingerprint2 = kInitialSize * 2 + 14;
+ const VisitedLinkCommon::Fingerprint kFingerprint3 = kInitialSize * 3 + 14;
+ const VisitedLinkCommon::Fingerprint kFingerprint4 = kInitialSize * 4 + 14;
master_->AddFingerprint(kFingerprint0); // @14
master_->AddFingerprint(kFingerprint1); // @15
master_->AddFingerprint(kFingerprint2); // @16
@@ -193,8 +191,9 @@ TEST_F(VisitedLinkTest, Delete) {
// order).
EXPECT_EQ(kFingerprint3, master_->hash_table_[0]);
master_->DeleteFingerprint(kFingerprint3, false);
- EXPECT_EQ(0, master_->hash_table_[1]);
- EXPECT_NE(0, master_->hash_table_[0]);
+ VisitedLinkCommon::Fingerprint zero_fingerprint = 0;
+ EXPECT_EQ(zero_fingerprint, master_->hash_table_[1]);
+ EXPECT_NE(zero_fingerprint, master_->hash_table_[0]);
// Deleting the other four should leave the table empty.
master_->DeleteFingerprint(kFingerprint0, false);
@@ -204,7 +203,8 @@ TEST_F(VisitedLinkTest, Delete) {
EXPECT_EQ(0, master_->used_items_);
for (int i = 0; i < kInitialSize; i++)
- EXPECT_EQ(0, master_->hash_table_[i]) << "Hash table has values in it.";
+ EXPECT_EQ(zero_fingerprint, master_->hash_table_[i]) <<
+ "Hash table has values in it.";
}
// When we delete more than kBigDeleteThreshold we trigger different behavior
@@ -240,7 +240,7 @@ TEST_F(VisitedLinkTest, DeleteAll) {
{
VisitedLinkSlave slave;
base::SharedMemoryHandle new_handle = NULL;
- master_->ShareToProcess(GetCurrentProcess(), &new_handle);
+ master_->ShareToProcess(base::GetCurrentProcessHandle(), &new_handle);
ASSERT_TRUE(slave.Init(new_handle));
g_slaves.push_back(&slave);
@@ -288,7 +288,7 @@ TEST_F(VisitedLinkTest, Resizing) {
// ...and a slave
VisitedLinkSlave slave;
base::SharedMemoryHandle new_handle = NULL;
- master_->ShareToProcess(GetCurrentProcess(), &new_handle);
+ master_->ShareToProcess(base::GetCurrentProcessHandle(), &new_handle);
bool success = slave.Init(new_handle);
ASSERT_TRUE(success);
g_slaves.push_back(&slave);
diff --git a/chrome/chrome.xcodeproj/project.pbxproj b/chrome/chrome.xcodeproj/project.pbxproj
index e570354..4f14b07 100644
--- a/chrome/chrome.xcodeproj/project.pbxproj
+++ b/chrome/chrome.xcodeproj/project.pbxproj
@@ -227,6 +227,7 @@
B56E281B0F057F2800447108 /* message_router.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D7BFBD10E9D4C9F009A6919 /* message_router.cc */; };
B5DBEA900EFC60E200C95176 /* ipc_channel_proxy.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D7BFBAB0E9D4C9F009A6919 /* ipc_channel_proxy.cc */; };
B5E98B140F0574A8000A37D6 /* render_messages.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D7BFBF10E9D4C9F009A6919 /* render_messages.cc */; };
+ B5FCDE5C0F269E9B0099BFAF /* visitedlink_master.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D7BF95F0E9D4839009A6919 /* visitedlink_master.cc */; };
B5FDC0580EE488E500BEC6E6 /* ipc_channel_posix.cc in Sources */ = {isa = PBXBuildFile; fileRef = B5FDC0570EE488E500BEC6E6 /* ipc_channel_posix.cc */; };
B5FDC1CA0EE48ADB00BEC6E6 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4D7BFDD10E9D5295009A6919 /* CoreFoundation.framework */; };
B5FDC1CC0EE48ADB00BEC6E6 /* libbase.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4D7BFDC70E9D525B009A6919 /* libbase.a */; };
@@ -4193,6 +4194,7 @@
4D7BFA480E9D4922009A6919 /* visitsegment_database.cc in Sources */,
E48B6C3C0F27844F002E47EC /* web_data_service.cc in Sources */,
E45076200F150E0C003BE099 /* web_database.cc in Sources */,
+ B5FCDE5C0F269E9B0099BFAF /* visitedlink_master.cc in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
diff --git a/chrome/common/temp_scaffolding_stubs.h b/chrome/common/temp_scaffolding_stubs.h
index aad59bd..e6264da 100644
--- a/chrome/common/temp_scaffolding_stubs.h
+++ b/chrome/common/temp_scaffolding_stubs.h
@@ -22,14 +22,19 @@
#include "webkit/glue/window_open_disposition.h"
class Browser;
+class BookmarkService;
class CommandLine;
+class HistoryService;
class MetricsService;
class NavigationEntry;
class ProfileManager;
class Profile;
class SessionID;
+class SpellChecker;
class TabContents;
class URLRequestContext;
+class UserScriptMaster;
+class VisitedLinkMaster;
class WebContents;
//---------------------------------------------------------------------------
@@ -175,24 +180,63 @@ class TabRestoreService {
void BrowserClosed(Browser*) { }
};
+class HistoryService {
+ public:
+
+ class URLEnumerator {
+ public:
+ virtual ~URLEnumerator() {}
+ virtual void OnURL(const GURL& url) = 0;
+ virtual void OnComplete(bool success) = 0;
+ };
+
+ HistoryService() {}
+ bool Init(const std::wstring& history_dir, BookmarkService* bookmark_service)
+ { return false; }
+ void SetOnBackendDestroyTask(Task*) {}
+ void AddPage(GURL const&, void const*, int, GURL const&,
+ int, std::vector<GURL> const&) {}
+ void AddPage(const GURL& url) {}
+ void SetPageContents(const GURL& url, const std::wstring& contents) {}
+ void IterateURLs(URLEnumerator* iterator) {}
+ void Cleanup() {}
+ void AddRef() {}
+ void Release() {}
+};
+
class Profile {
public:
+ enum ServiceAccessType {
+ EXPLICIT_ACCESS,
+ IMPLICIT_ACCESS
+ };
+
+ public:
Profile(const std::wstring& user_data_dir);
virtual std::wstring GetPath() { return path_; }
virtual PrefService* GetPrefs();
void ResetTabRestoreService() { }
+ SpellChecker* GetSpellChecker() { return NULL; }
+ VisitedLinkMaster* GetVisitedLinkMaster() { return NULL; }
TabRestoreService* GetTabRestoreService() { return NULL; }
SessionService* GetSessionService() { return NULL; }
+ UserScriptMaster* GetUserScriptMaster() { return NULL; }
bool IsOffTheRecord() { return false; }
URLRequestContext* GetRequestContext() { return NULL; }
virtual Profile* GetOriginalProfile() { return this; }
virtual Profile* GetOffTheRecordProfile() { return this; }
bool HasSessionService() { return false; }
+ std::wstring GetID() { return L""; }
+ HistoryService* GetHistoryService(ServiceAccessType access) {
+ return &history_service_;
+ }
+
private:
std::wstring GetPrefFilePath();
std::wstring path_;
scoped_ptr<PrefService> prefs_;
+ HistoryService history_service_;
};
class ProfileManager : NonThreadSafe {