summaryrefslogtreecommitdiffstats
path: root/base
diff options
context:
space:
mode:
authorKristian Monsen <kristianm@google.com>2011-06-28 21:49:31 +0100
committerKristian Monsen <kristianm@google.com>2011-07-08 17:55:00 +0100
commitddb351dbec246cf1fab5ec20d2d5520909041de1 (patch)
tree158e3fb57bdcac07c7f1e767fde3c70687c9fbb1 /base
parent6b92e04f5f151c896e3088e86f70db7081009308 (diff)
downloadexternal_chromium-ddb351dbec246cf1fab5ec20d2d5520909041de1.zip
external_chromium-ddb351dbec246cf1fab5ec20d2d5520909041de1.tar.gz
external_chromium-ddb351dbec246cf1fab5ec20d2d5520909041de1.tar.bz2
Merge Chromium at r12.0.742.93: Initial merge by git
Change-Id: Ic5ee2fec31358bbee305f7e915442377bfa6cda6
Diffstat (limited to 'base')
-rw-r--r--base/OWNERS6
-rw-r--r--base/allocator/allocator_shim.cc2
-rw-r--r--base/at_exit.cc6
-rw-r--r--base/at_exit.h3
-rw-r--r--base/atomic_ref_count.h4
-rw-r--r--base/atomicops.h10
-rw-r--r--base/atomicops_internals_atomicword_compat.h101
-rw-r--r--base/atomicops_internals_x86_macosx.h85
-rw-r--r--base/atomicops_unittest.cc6
-rw-r--r--base/base.gyp74
-rw-r--r--base/base.gypi187
-rw-r--r--base/base64.h8
-rw-r--r--base/base_api.h19
-rw-r--r--base/base_paths.h5
-rw-r--r--base/base_paths_linux.cc18
-rw-r--r--base/base_paths_mac.mm27
-rw-r--r--base/basictypes.h11
-rw-r--r--base/bind_helpers.h52
-rw-r--r--base/bind_internal.h795
-rw-r--r--base/bind_internal.h.pump67
-rw-r--r--base/bind_internal_win.h55
-rw-r--r--base/bind_internal_win.h.pump20
-rw-r--r--base/bind_unittest.cc52
-rw-r--r--base/bzip2_error_handler.cc4
-rw-r--r--base/callback.h106
-rw-r--r--base/callback.h.pump8
-rw-r--r--base/callback_internal.h53
-rw-r--r--base/callback_old.h4
-rw-r--r--base/callback_unittest.cc4
-rw-r--r--base/command_line.cc9
-rw-r--r--base/command_line.h5
-rw-r--r--base/compiler_specific.h4
-rw-r--r--base/cpu.cc4
-rw-r--r--base/cpu.h8
-rw-r--r--base/crypto/capi_util.cc50
-rw-r--r--base/crypto/capi_util.h32
-rw-r--r--base/crypto/crypto_module_blocking_password_delegate.h34
-rw-r--r--base/crypto/cssm_init.cc231
-rw-r--r--base/crypto/cssm_init.h69
-rw-r--r--base/crypto/encryptor.h69
-rw-r--r--base/crypto/encryptor_mac.cc76
-rw-r--r--base/crypto/encryptor_nss.cc125
-rw-r--r--base/crypto/encryptor_openssl.cc127
-rw-r--r--base/crypto/encryptor_unittest.cc232
-rw-r--r--base/crypto/encryptor_win.cc115
-rw-r--r--base/crypto/rsa_private_key.cc390
-rw-r--r--base/crypto/rsa_private_key.h273
-rw-r--r--base/crypto/rsa_private_key_mac.cc196
-rw-r--r--base/crypto/rsa_private_key_nss.cc248
-rw-r--r--base/crypto/rsa_private_key_nss_unittest.cc64
-rw-r--r--base/crypto/rsa_private_key_openssl.cc135
-rw-r--r--base/crypto/rsa_private_key_unittest.cc383
-rw-r--r--base/crypto/rsa_private_key_win.cc229
-rw-r--r--base/crypto/scoped_capi_types.h125
-rw-r--r--base/crypto/scoped_nss_types.h52
-rw-r--r--base/crypto/secure_hash.h36
-rw-r--r--base/crypto/secure_hash_default.cc49
-rw-r--r--base/crypto/secure_hash_openssl.cc53
-rw-r--r--base/crypto/secure_hash_unittest.cc34
-rw-r--r--base/crypto/signature_creator.h69
-rw-r--r--base/crypto/signature_creator_mac.cc74
-rw-r--r--base/crypto/signature_creator_nss.cc76
-rw-r--r--base/crypto/signature_creator_openssl.cc54
-rw-r--r--base/crypto/signature_creator_unittest.cc53
-rw-r--r--base/crypto/signature_creator_win.cc60
-rw-r--r--base/crypto/signature_verifier.h108
-rw-r--r--base/crypto/signature_verifier_mac.cc105
-rw-r--r--base/crypto/signature_verifier_nss.cc113
-rw-r--r--base/crypto/signature_verifier_openssl.cc94
-rw-r--r--base/crypto/signature_verifier_unittest.cc268
-rw-r--r--base/crypto/signature_verifier_win.cc134
-rw-r--r--base/crypto/symmetric_key.h104
-rw-r--r--base/crypto/symmetric_key_mac.cc155
-rw-r--r--base/crypto/symmetric_key_nss.cc127
-rw-r--r--base/crypto/symmetric_key_openssl.cc76
-rw-r--r--base/crypto/symmetric_key_unittest.cc226
-rw-r--r--base/crypto/symmetric_key_win.cc536
-rw-r--r--base/debug/debug_on_start_win.h7
-rw-r--r--base/debug/debugger.h16
-rw-r--r--base/debug/debugger_posix.cc5
-rw-r--r--base/debug/leak_tracker_unittest.cc4
-rw-r--r--base/debug/stack_trace.cc4
-rw-r--r--base/debug/stack_trace.h11
-rw-r--r--base/debug/stack_trace_posix.cc17
-rw-r--r--base/debug/stack_trace_win.cc8
-rw-r--r--base/debug/trace_event.h6
-rw-r--r--base/debug/trace_event_win.cc4
-rw-r--r--base/debug/trace_event_win.h12
-rw-r--r--base/environment.cc4
-rw-r--r--base/environment.h7
-rw-r--r--base/environment_unittest.cc4
-rw-r--r--base/event_recorder.cc5
-rw-r--r--base/event_recorder.h10
-rw-r--r--base/file_descriptor_shuffle.cc5
-rw-r--r--base/file_path.cc28
-rw-r--r--base/file_path.h16
-rw-r--r--base/file_util.h178
-rw-r--r--base/file_util_deprecated.h23
-rw-r--r--base/file_util_linux.cc5
-rw-r--r--base/file_util_posix.cc35
-rw-r--r--base/file_util_proxy.cc5
-rw-r--r--base/file_util_proxy.h5
-rw-r--r--base/file_util_unittest.cc6
-rw-r--r--base/file_util_win.cc47
-rw-r--r--base/file_version_info.h8
-rw-r--r--base/file_version_info_mac.h4
-rw-r--r--base/file_version_info_mac.mm5
-rw-r--r--base/file_version_info_unittest.cc4
-rw-r--r--base/file_version_info_win.cc5
-rw-r--r--base/file_version_info_win.h7
-rw-r--r--base/files/OWNERS3
-rw-r--r--base/files/file_path_watcher.cc33
-rw-r--r--base/files/file_path_watcher.h128
-rw-r--r--base/files/file_path_watcher_browsertest.cc622
-rw-r--r--base/files/file_path_watcher_linux.cc462
-rw-r--r--base/files/file_path_watcher_mac.cc493
-rw-r--r--base/files/file_path_watcher_stub.cc31
-rw-r--r--base/files/file_path_watcher_win.cc281
-rw-r--r--base/global_descriptors_posix.h2
-rw-r--r--base/hmac.h60
-rw-r--r--base/hmac_mac.cc73
-rw-r--r--base/hmac_nss.cc117
-rw-r--r--base/hmac_openssl.cc57
-rw-r--r--base/hmac_unittest.cc236
-rw-r--r--base/hmac_win.cc197
-rw-r--r--base/i18n/break_iterator.cc6
-rw-r--r--base/i18n/break_iterator.h31
-rw-r--r--base/i18n/file_util_icu.cc6
-rw-r--r--base/i18n/file_util_icu_unittest.cc23
-rw-r--r--base/i18n/icu_encoding_detection.cc42
-rw-r--r--base/i18n/icu_encoding_detection.h4
-rw-r--r--base/i18n/icu_util.cc2
-rw-r--r--base/i18n/number_formatting.cc4
-rw-r--r--base/i18n/rtl_unittest.cc98
-rw-r--r--base/i18n/time_formatting.cc74
-rw-r--r--base/i18n/time_formatting.h19
-rw-r--r--base/json/json_reader.cc4
-rw-r--r--base/json/json_reader.h3
-rw-r--r--base/json/json_reader_unittest.cc4
-rw-r--r--base/json/json_writer.h5
-rw-r--r--base/json/string_escape.h19
-rw-r--r--base/lazy_instance.h5
-rw-r--r--base/linux_util.cc8
-rw-r--r--base/logging.cc19
-rw-r--r--base/logging.h52
-rw-r--r--base/logging_unittest.cc7
-rw-r--r--base/logging_win.cc4
-rw-r--r--base/logging_win.h6
-rw-r--r--base/mac/OWNERS2
-rw-r--r--base/mac/foundation_util.mm4
-rw-r--r--base/mac/mac_util.mm8
-rw-r--r--base/mac/mac_util_unittest.mm2
-rw-r--r--base/mach_ipc_mac.h13
-rw-r--r--base/mach_ipc_mac.mm8
-rw-r--r--base/md5.h16
-rw-r--r--base/memory/linked_ptr.h (renamed from base/linked_ptr.h)8
-rw-r--r--base/memory/linked_ptr_unittest.cc (renamed from base/linked_ptr_unittest.cc)4
-rw-r--r--base/memory/memory_debug.cc (renamed from base/memory_debug.cc)4
-rw-r--r--base/memory/memory_debug.h (renamed from base/memory_debug.h)11
-rw-r--r--base/memory/raw_scoped_refptr_mismatch_checker.h (renamed from base/raw_scoped_refptr_mismatch_checker.h)10
-rw-r--r--base/memory/ref_counted.cc (renamed from base/ref_counted.cc)4
-rw-r--r--base/memory/ref_counted.h (renamed from base/ref_counted.h)13
-rw-r--r--base/memory/ref_counted_memory.cc (renamed from base/ref_counted_memory.cc)4
-rw-r--r--base/memory/ref_counted_memory.h (renamed from base/ref_counted_memory.h)16
-rw-r--r--base/memory/ref_counted_unittest.cc (renamed from base/ref_counted_unittest.cc)4
-rw-r--r--base/memory/scoped_callback_factory.h (renamed from base/scoped_callback_factory.h)10
-rw-r--r--base/memory/scoped_handle.h (renamed from base/scoped_handle.h)6
-rw-r--r--base/memory/scoped_native_library.cc (renamed from base/scoped_native_library.cc)6
-rw-r--r--base/memory/scoped_native_library.h (renamed from base/scoped_native_library.h)11
-rw-r--r--base/memory/scoped_native_library_unittest.cc (renamed from base/scoped_native_library_unittest.cc)4
-rw-r--r--base/memory/scoped_nsobject.h (renamed from base/scoped_nsobject.h)8
-rw-r--r--base/memory/scoped_open_process.h (renamed from base/scoped_open_process.h)8
-rw-r--r--base/memory/scoped_ptr.h383
-rw-r--r--base/memory/scoped_ptr_unittest.cc (renamed from base/scoped_ptr_unittest.cc)4
-rw-r--r--base/memory/scoped_temp_dir.cc (renamed from base/scoped_temp_dir.cc)4
-rw-r--r--base/memory/scoped_temp_dir.h (renamed from base/scoped_temp_dir.h)11
-rw-r--r--base/memory/scoped_temp_dir_unittest.cc (renamed from base/scoped_temp_dir_unittest.cc)4
-rw-r--r--base/memory/scoped_vector.h (renamed from base/scoped_vector.h)14
-rw-r--r--base/memory/scoped_vector_unittest.cc156
-rw-r--r--base/memory/singleton.h (renamed from base/singleton.h)10
-rw-r--r--base/memory/singleton_objc.h (renamed from base/singleton_objc.h)10
-rw-r--r--base/memory/singleton_unittest.cc (renamed from base/singleton_unittest.cc)4
-rw-r--r--base/memory/weak_ptr.cc (renamed from base/weak_ptr.cc)24
-rw-r--r--base/memory/weak_ptr.h (renamed from base/weak_ptr.h)44
-rw-r--r--base/memory/weak_ptr_unittest.cc (renamed from base/weak_ptr_unittest.cc)6
-rw-r--r--base/message_loop.cc10
-rw-r--r--base/message_loop.h29
-rw-r--r--base/message_loop_proxy.h14
-rw-r--r--base/message_loop_proxy_impl.h7
-rw-r--r--base/message_loop_proxy_impl_unittest.cc4
-rw-r--r--base/message_loop_unittest.cc2
-rw-r--r--base/message_pump.h9
-rw-r--r--base/message_pump_glib.h2
-rw-r--r--base/message_pump_glib_unittest.cc4
-rw-r--r--base/message_pump_glib_x.cc42
-rw-r--r--base/message_pump_glib_x.h11
-rw-r--r--base/message_pump_libevent.cc4
-rw-r--r--base/message_pump_mac.h14
-rw-r--r--base/message_pump_mac.mm92
-rw-r--r--base/message_pump_win.cc21
-rw-r--r--base/message_pump_win.h7
-rw-r--r--base/metrics/field_trial.h49
-rw-r--r--base/metrics/histogram.cc158
-rw-r--r--base/metrics/histogram.h177
-rw-r--r--base/metrics/histogram_unittest.cc117
-rw-r--r--base/metrics/stats_counters.cc16
-rw-r--r--base/metrics/stats_counters.h13
-rw-r--r--base/metrics/stats_table.cc2
-rw-r--r--base/metrics/stats_table.h3
-rw-r--r--base/mime_util_xdg.cc21
-rw-r--r--base/native_library.h21
-rw-r--r--base/native_library_linux.cc17
-rw-r--r--base/native_library_mac.mm5
-rw-r--r--base/native_library_win.cc5
-rw-r--r--base/nix/xdg_util.cc3
-rw-r--r--base/nss_util.cc436
-rw-r--r--base/nss_util.h85
-rw-r--r--base/nss_util_internal.h22
-rw-r--r--base/observer_list_threadsafe.h4
-rw-r--r--base/observer_list_unittest.cc4
-rw-r--r--base/openssl_util.cc113
-rw-r--r--base/path_service.cc8
-rw-r--r--base/path_service.h8
-rw-r--r--base/pickle.cc4
-rw-r--r--base/pickle.h3
-rw-r--r--base/pickle_unittest.cc4
-rw-r--r--base/platform_file.h46
-rw-r--r--base/platform_file_posix.cc19
-rw-r--r--base/platform_file_unittest.cc4
-rw-r--r--base/platform_file_win.cc6
-rw-r--r--base/process.h7
-rw-r--r--base/process_linux.cc62
-rw-r--r--base/process_util.h122
-rw-r--r--base/process_util_mac.mm57
-rw-r--r--base/process_util_posix.cc74
-rw-r--r--base/process_util_unittest.cc4
-rw-r--r--base/process_util_win.cc28
-rw-r--r--base/process_win.cc4
-rw-r--r--base/rand_util.cc2
-rw-r--r--base/rand_util.h11
-rw-r--r--base/resource_util.h7
-rw-r--r--base/scoped_comptr_win.h9
-rw-r--r--base/scoped_ptr.h378
-rw-r--r--base/sha1.h11
-rw-r--r--base/sha1_portable.cc17
-rw-r--r--base/sha1_unittest.cc52
-rw-r--r--base/sha1_win.cc6
-rw-r--r--base/sha2.cc29
-rw-r--r--base/sha2.h32
-rw-r--r--base/sha2_openssl.cc30
-rw-r--r--base/sha2_unittest.cc97
-rw-r--r--base/shared_memory.h5
-rw-r--r--base/shared_memory_posix.cc10
-rw-r--r--base/shared_memory_unittest.cc4
-rw-r--r--base/stack_container_unittest.cc4
-rw-r--r--base/string_number_conversions.h85
-rw-r--r--base/string_piece.cc7
-rw-r--r--base/string_piece.h5
-rw-r--r--base/string_split.h61
-rw-r--r--base/string_util.cc4
-rw-r--r--base/string_util.h307
-rw-r--r--base/string_util_posix.h9
-rw-r--r--base/stringprintf.h27
-rw-r--r--base/sync_socket.h6
-rw-r--r--base/synchronization/cancellation_flag.h3
-rw-r--r--base/synchronization/condition_variable.h3
-rw-r--r--base/synchronization/condition_variable_unittest.cc2
-rw-r--r--base/synchronization/lock.h3
-rw-r--r--base/synchronization/waitable_event.h5
-rw-r--r--base/synchronization/waitable_event_watcher.h4
-rw-r--r--base/sys_info.h17
-rw-r--r--base/sys_info_chromeos.cc96
-rw-r--r--base/sys_info_mac.cc8
-rw-r--r--base/sys_info_unittest.cc12
-rw-r--r--base/sys_info_win.cc43
-rw-r--r--base/sys_string_conversions.h18
-rw-r--r--base/task.h11
-rw-r--r--base/task_queue.h3
-rw-r--r--base/task_queue_unittest.cc4
-rw-r--r--base/task_unittest.cc4
-rw-r--r--base/test/OWNERS1
-rw-r--r--base/test/test_file_util.h1
-rw-r--r--base/test/test_file_util_posix.cc3
-rw-r--r--base/test/test_file_util_win.cc3
-rw-r--r--base/test/test_suite.cc11
-rw-r--r--base/test/test_switches.cc3
-rw-r--r--base/test/test_switches.h3
-rw-r--r--base/test/test_timeouts.cc9
-rw-r--r--base/test/test_timeouts.h9
-rw-r--r--base/third_party/nspr/prcpucfg.h6
-rw-r--r--base/third_party/nspr/prcpucfg_mac.h54
-rw-r--r--base/third_party/nspr/prcpucfg_nacl.h246
-rw-r--r--base/third_party/nspr/prtime.cc3
-rw-r--r--base/third_party/nspr/prtime.h11
-rw-r--r--base/third_party/nspr/prtypes.h118
-rw-r--r--base/threading/non_thread_safe.h2
-rw-r--r--base/threading/non_thread_safe_impl.h3
-rw-r--r--base/threading/non_thread_safe_unittest.cc4
-rw-r--r--base/threading/platform_thread.h7
-rw-r--r--base/threading/platform_thread_posix.cc4
-rw-r--r--base/threading/simple_thread.h12
-rw-r--r--base/threading/thread.h3
-rw-r--r--base/threading/thread_checker_impl.h3
-rw-r--r--base/threading/thread_checker_unittest.cc4
-rw-r--r--base/threading/thread_collision_warner.h15
-rw-r--r--base/threading/thread_collision_warner_unittest.cc4
-rw-r--r--base/threading/thread_local.h5
-rw-r--r--base/threading/thread_local_storage.h7
-rw-r--r--base/threading/thread_restrictions.h9
-rw-r--r--base/threading/watchdog.h3
-rw-r--r--base/threading/worker_pool.h5
-rw-r--r--base/threading/worker_pool_posix.cc4
-rw-r--r--base/threading/worker_pool_posix.h6
-rw-r--r--base/time.h9
-rw-r--r--base/time_posix.cc11
-rw-r--r--base/time_win.cc4
-rw-r--r--base/timer.h11
-rw-r--r--base/timer_unittest.cc4
-rw-r--r--base/tracked.h7
-rw-r--r--base/tracked_objects.cc2
-rw-r--r--base/tracked_objects.h26
-rw-r--r--base/utf_offset_string_conversions.cc169
-rw-r--r--base/utf_offset_string_conversions.h98
-rw-r--r--base/utf_offset_string_conversions_unittest.cc94
-rw-r--r--base/utf_string_conversions.h38
-rw-r--r--base/value_conversions.cc52
-rw-r--r--base/value_conversions.h25
-rw-r--r--base/values.cc39
-rw-r--r--base/values.h26
-rw-r--r--base/values_unittest.cc4
-rw-r--r--base/version.h3
-rw-r--r--base/version_unittest.cc4
-rw-r--r--base/vlog.h9
-rw-r--r--base/win/event_trace_controller.h8
-rw-r--r--base/win/event_trace_provider.h6
-rw-r--r--base/win/i18n.h9
-rw-r--r--base/win/object_watcher.h3
-rw-r--r--base/win/registry.h7
-rw-r--r--base/win/scoped_bstr.h5
-rw-r--r--base/win/scoped_comptr.h4
-rw-r--r--base/win/scoped_comptr_unittest.cc6
-rw-r--r--base/win/scoped_variant.h5
-rw-r--r--base/win/win_util.cc2
-rw-r--r--base/win/win_util.h29
-rw-r--r--base/win/windows_version.cc100
-rw-r--r--base/win/windows_version.h119
-rw-r--r--base/win/wrapped_window_proc.cc32
-rw-r--r--base/win/wrapped_window_proc.h69
-rw-r--r--base/win/wrapped_window_proc_unittest.cc79
349 files changed, 6816 insertions, 10626 deletions
diff --git a/base/OWNERS b/base/OWNERS
new file mode 100644
index 0000000..41dd3c9
--- /dev/null
+++ b/base/OWNERS
@@ -0,0 +1,6 @@
+set noparent
+mark@chromium.org
+darin@chromium.org
+brettw@chromium.org
+evan@chromium.org
+willchan@chromium.org
diff --git a/base/allocator/allocator_shim.cc b/base/allocator/allocator_shim.cc
index f11164c..97946e7 100644
--- a/base/allocator/allocator_shim.cc
+++ b/base/allocator/allocator_shim.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
diff --git a/base/at_exit.cc b/base/at_exit.cc
index e6618a0..e467c5d 100644
--- a/base/at_exit.cc
+++ b/base/at_exit.cc
@@ -1,8 +1,12 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
#include "base/at_exit.h"
+
+#include <stddef.h>
+#include <ostream>
+
#include "base/logging.h"
namespace base {
diff --git a/base/at_exit.h b/base/at_exit.h
index 15dcfc8..06214d1 100644
--- a/base/at_exit.h
+++ b/base/at_exit.h
@@ -8,6 +8,7 @@
#include <stack>
+#include "base/base_api.h"
#include "base/basictypes.h"
#include "base/synchronization/lock.h"
@@ -27,7 +28,7 @@ namespace base {
// When the exit_manager object goes out of scope, all the registered
// callbacks and singleton destructors will be called.
-class AtExitManager {
+class BASE_API AtExitManager {
public:
typedef void (*AtExitCallbackType)(void*);
diff --git a/base/atomic_ref_count.h b/base/atomic_ref_count.h
index dff4b1f..985c42c 100644
--- a/base/atomic_ref_count.h
+++ b/base/atomic_ref_count.h
@@ -1,9 +1,9 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
// This is a low level implementation of atomic semantics for reference
-// counting. Please use base/ref_counted.h directly instead.
+// counting. Please use base/memory/ref_counted.h directly instead.
//
// The implementation includes annotations to avoid some false positives
// when using data race detection tools.
diff --git a/base/atomicops.h b/base/atomicops.h
index 445696b..5b2b9dd 100644
--- a/base/atomicops.h
+++ b/base/atomicops.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -30,7 +30,7 @@
#pragma once
#include "base/basictypes.h"
-#include "base/port.h"
+#include "build/build_config.h"
namespace base {
namespace subtle {
@@ -145,4 +145,10 @@ Atomic64 Release_Load(volatile const Atomic64* ptr);
#error "Atomic operations are not supported on your platform"
#endif
+// On some platforms we need additional declarations to make
+// AtomicWord compatible with our other Atomic* types.
+#if defined(OS_MACOSX) || defined(OS_OPENBSD)
+#include "base/atomicops_internals_atomicword_compat.h"
+#endif
+
#endif // BASE_ATOMICOPS_H_
diff --git a/base/atomicops_internals_atomicword_compat.h b/base/atomicops_internals_atomicword_compat.h
new file mode 100644
index 0000000..8382fe1
--- /dev/null
+++ b/base/atomicops_internals_atomicword_compat.h
@@ -0,0 +1,101 @@
+// Copyright (c) 2011 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.
+
+// This file is an internal atomic implementation, use base/atomicops.h instead.
+
+#ifndef BASE_ATOMICOPS_INTERNALS_ATOMICWORD_COMPAT_H_
+#define BASE_ATOMICOPS_INTERNALS_ATOMICWORD_COMPAT_H_
+#pragma once
+
+// AtomicWord is a synonym for intptr_t, and Atomic32 is a synonym for int32,
+// which in turn means int. On some LP32 platforms, intptr_t is an int, but
+// on others, it's a long. When AtomicWord and Atomic32 are based on different
+// fundamental types, their pointers are incompatible.
+//
+// This file defines function overloads to allow both AtomicWord and Atomic32
+// data to be used with this interface.
+//
+// On LP64 platforms, AtomicWord and Atomic64 are both always long,
+// so this problem doesn't occur.
+
+#if !defined(ARCH_CPU_64_BITS)
+
+namespace base {
+namespace subtle {
+
+inline AtomicWord NoBarrier_CompareAndSwap(volatile AtomicWord* ptr,
+ AtomicWord old_value,
+ AtomicWord new_value) {
+ return NoBarrier_CompareAndSwap(
+ reinterpret_cast<volatile Atomic32*>(ptr), old_value, new_value);
+}
+
+inline AtomicWord NoBarrier_AtomicExchange(volatile AtomicWord* ptr,
+ AtomicWord new_value) {
+ return NoBarrier_AtomicExchange(
+ reinterpret_cast<volatile Atomic32*>(ptr), new_value);
+}
+
+inline AtomicWord NoBarrier_AtomicIncrement(volatile AtomicWord* ptr,
+ AtomicWord increment) {
+ return NoBarrier_AtomicIncrement(
+ reinterpret_cast<volatile Atomic32*>(ptr), increment);
+}
+
+inline AtomicWord Barrier_AtomicIncrement(volatile AtomicWord* ptr,
+ AtomicWord increment) {
+ return Barrier_AtomicIncrement(
+ reinterpret_cast<volatile Atomic32*>(ptr), increment);
+}
+
+inline AtomicWord Acquire_CompareAndSwap(volatile AtomicWord* ptr,
+ AtomicWord old_value,
+ AtomicWord new_value) {
+ return base::subtle::Acquire_CompareAndSwap(
+ reinterpret_cast<volatile Atomic32*>(ptr), old_value, new_value);
+}
+
+inline AtomicWord Release_CompareAndSwap(volatile AtomicWord* ptr,
+ AtomicWord old_value,
+ AtomicWord new_value) {
+ return base::subtle::Release_CompareAndSwap(
+ reinterpret_cast<volatile Atomic32*>(ptr), old_value, new_value);
+}
+
+inline void NoBarrier_Store(volatile AtomicWord *ptr, AtomicWord value) {
+ NoBarrier_Store(
+ reinterpret_cast<volatile Atomic32*>(ptr), value);
+}
+
+inline void Acquire_Store(volatile AtomicWord* ptr, AtomicWord value) {
+ return base::subtle::Acquire_Store(
+ reinterpret_cast<volatile Atomic32*>(ptr), value);
+}
+
+inline void Release_Store(volatile AtomicWord* ptr, AtomicWord value) {
+ return base::subtle::Release_Store(
+ reinterpret_cast<volatile Atomic32*>(ptr), value);
+}
+
+inline AtomicWord NoBarrier_Load(volatile const AtomicWord *ptr) {
+ return NoBarrier_Load(
+ reinterpret_cast<volatile const Atomic32*>(ptr));
+}
+
+inline AtomicWord Acquire_Load(volatile const AtomicWord* ptr) {
+ return base::subtle::Acquire_Load(
+ reinterpret_cast<volatile const Atomic32*>(ptr));
+}
+
+inline AtomicWord Release_Load(volatile const AtomicWord* ptr) {
+ return base::subtle::Release_Load(
+ reinterpret_cast<volatile const Atomic32*>(ptr));
+}
+
+} // namespace base::subtle
+} // namespace base
+
+#endif // !defined(ARCH_CPU_64_BITS)
+
+#endif // BASE_ATOMICOPS_INTERNALS_ATOMICWORD_COMPAT_H_
diff --git a/base/atomicops_internals_x86_macosx.h b/base/atomicops_internals_x86_macosx.h
index 29e58e3..4b7cec8 100644
--- a/base/atomicops_internals_x86_macosx.h
+++ b/base/atomicops_internals_x86_macosx.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -192,89 +192,6 @@ inline Atomic64 Release_Load(volatile const Atomic64 *ptr) {
#endif // defined(__LP64__)
-// MacOS uses long for intptr_t, AtomicWord and Atomic32 are always different
-// on the Mac, even when they are the same size. We need to explicitly cast
-// from AtomicWord to Atomic32 to implement the AtomicWord interface.
-// When in 64-bit mode, AtomicWord is the same as Atomic64, so we need not
-// add duplicate definitions.
-#ifndef __LP64__
-#define AtomicWordCastType Atomic32
-
-inline AtomicWord NoBarrier_CompareAndSwap(volatile AtomicWord* ptr,
- AtomicWord old_value,
- AtomicWord new_value) {
- return NoBarrier_CompareAndSwap(
- reinterpret_cast<volatile AtomicWordCastType*>(ptr),
- old_value, new_value);
-}
-
-inline AtomicWord NoBarrier_AtomicExchange(volatile AtomicWord* ptr,
- AtomicWord new_value) {
- return NoBarrier_AtomicExchange(
- reinterpret_cast<volatile AtomicWordCastType*>(ptr), new_value);
-}
-
-inline AtomicWord NoBarrier_AtomicIncrement(volatile AtomicWord* ptr,
- AtomicWord increment) {
- return NoBarrier_AtomicIncrement(
- reinterpret_cast<volatile AtomicWordCastType*>(ptr), increment);
-}
-
-inline AtomicWord Barrier_AtomicIncrement(volatile AtomicWord* ptr,
- AtomicWord increment) {
- return Barrier_AtomicIncrement(
- reinterpret_cast<volatile AtomicWordCastType*>(ptr), increment);
-}
-
-inline AtomicWord Acquire_CompareAndSwap(volatile AtomicWord* ptr,
- AtomicWord old_value,
- AtomicWord new_value) {
- return base::subtle::Acquire_CompareAndSwap(
- reinterpret_cast<volatile AtomicWordCastType*>(ptr),
- old_value, new_value);
-}
-
-inline AtomicWord Release_CompareAndSwap(volatile AtomicWord* ptr,
- AtomicWord old_value,
- AtomicWord new_value) {
- return base::subtle::Release_CompareAndSwap(
- reinterpret_cast<volatile AtomicWordCastType*>(ptr),
- old_value, new_value);
-}
-
-inline void NoBarrier_Store(volatile AtomicWord *ptr, AtomicWord value) {
- NoBarrier_Store(
- reinterpret_cast<volatile AtomicWordCastType*>(ptr), value);
-}
-
-inline void Acquire_Store(volatile AtomicWord* ptr, AtomicWord value) {
- return base::subtle::Acquire_Store(
- reinterpret_cast<volatile AtomicWordCastType*>(ptr), value);
-}
-
-inline void Release_Store(volatile AtomicWord* ptr, AtomicWord value) {
- return base::subtle::Release_Store(
- reinterpret_cast<volatile AtomicWordCastType*>(ptr), value);
-}
-
-inline AtomicWord NoBarrier_Load(volatile const AtomicWord *ptr) {
- return NoBarrier_Load(
- reinterpret_cast<volatile const AtomicWordCastType*>(ptr));
-}
-
-inline AtomicWord Acquire_Load(volatile const AtomicWord* ptr) {
- return base::subtle::Acquire_Load(
- reinterpret_cast<volatile const AtomicWordCastType*>(ptr));
-}
-
-inline AtomicWord Release_Load(volatile const AtomicWord* ptr) {
- return base::subtle::Release_Load(
- reinterpret_cast<volatile const AtomicWordCastType*>(ptr));
-}
-
-#undef AtomicWordCastType
-#endif
-
} // namespace base::subtle
} // namespace base
diff --git a/base/atomicops_unittest.cc b/base/atomicops_unittest.cc
index 5053b0b..d73a098 100644
--- a/base/atomicops_unittest.cc
+++ b/base/atomicops_unittest.cc
@@ -1,8 +1,12 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
#include "base/atomicops.h"
+
+#include <string.h>
+
+#include "base/port.h"
#include "testing/gtest/include/gtest/gtest.h"
template <class AtomicType>
diff --git a/base/base.gyp b/base/base.gyp
index 525d316..37b197d 100644
--- a/base/base.gyp
+++ b/base/base.gyp
@@ -54,6 +54,48 @@
],
},
{
+ # This is the subset of files from base that should not be used with a
+ # dynamic library.
+ 'target_name': 'base_static',
+ 'type': '<(library)',
+ 'sources': [
+ 'base_switches.cc',
+ 'base_switches.h',
+ 'win/pe_image.cc',
+ 'win/pe_image.h',
+ ],
+ 'include_dirs': [
+ '..',
+ ],
+ },
+ {
+ # TODO(rvargas): Remove this when gyp finally supports a clean model.
+ # See bug 36232.
+ 'target_name': 'base_static_win64',
+ 'type': '<(library)',
+ 'sources': [
+ 'base_switches.cc',
+ 'base_switches.h',
+ 'win/pe_image.cc',
+ 'win/pe_image.h',
+ ],
+ 'include_dirs': [
+ '..',
+ ],
+ 'configurations': {
+ 'Common_Base': {
+ 'msvs_target_platform': 'x64',
+ },
+ },
+ 'defines': [
+ 'NACL_WIN64',
+ ],
+ # TODO(rvargas): Bug 78117. Remove this.
+ 'msvs_disabled_warnings': [
+ 4244,
+ ],
+ },
+ {
'target_name': 'base_unittests',
'type': 'executable',
'msvs_guid': '27A30967-4BBA-48D1-8522-CDE95F7B1CEC',
@@ -70,13 +112,6 @@
'callback_unittest.cc',
'command_line_unittest.cc',
'cpu_unittest.cc',
- 'crypto/encryptor_unittest.cc',
- 'crypto/rsa_private_key_unittest.cc',
- 'crypto/rsa_private_key_nss_unittest.cc',
- 'crypto/secure_hash_unittest.cc',
- 'crypto/signature_creator_unittest.cc',
- 'crypto/signature_verifier_unittest.cc',
- 'crypto/symmetric_key_unittest.cc',
'debug/leak_tracker_unittest.cc',
'debug/stack_trace_unittest.cc',
'debug/trace_event_win_unittest.cc',
@@ -87,7 +122,6 @@
'file_util_unittest.cc',
'file_version_info_unittest.cc',
'gmock_unittest.cc',
- 'hmac_unittest.cc',
'id_map_unittest.cc',
'i18n/break_iterator_unittest.cc',
'i18n/char_iterator_unittest.cc',
@@ -99,9 +133,16 @@
'json/string_escape_unittest.cc',
'lazy_instance_unittest.cc',
'linked_list_unittest.cc',
- 'linked_ptr_unittest.cc',
'logging_unittest.cc',
'mac/mac_util_unittest.mm',
+ 'memory/linked_ptr_unittest.cc',
+ 'memory/ref_counted_unittest.cc',
+ 'memory/scoped_native_library_unittest.cc',
+ 'memory/scoped_ptr_unittest.cc',
+ 'memory/scoped_temp_dir_unittest.cc',
+ 'memory/scoped_vector_unittest.cc',
+ 'memory/singleton_unittest.cc',
+ 'memory/weak_ptr_unittest.cc',
'message_loop_proxy_impl_unittest.cc',
'message_loop_unittest.cc',
'message_pump_glib_unittest.cc',
@@ -117,14 +158,8 @@
'process_util_unittest_mac.h',
'process_util_unittest_mac.mm',
'rand_util_unittest.cc',
- 'ref_counted_unittest.cc',
- 'scoped_native_library_unittest.cc',
- 'scoped_ptr_unittest.cc',
- 'scoped_temp_dir_unittest.cc',
'sha1_unittest.cc',
- 'sha2_unittest.cc',
'shared_memory_unittest.cc',
- 'singleton_unittest.cc',
'stack_container_unittest.cc',
'string16_unittest.cc',
'string_number_conversions_unittest.cc',
@@ -167,7 +202,6 @@
'values_unittest.cc',
'version_unittest.cc',
'vlog_unittest.cc',
- 'weak_ptr_unittest.cc',
'win/event_trace_consumer_unittest.cc',
'win/event_trace_controller_unittest.cc',
'win/event_trace_provider_unittest.cc',
@@ -179,10 +213,12 @@
'win/scoped_comptr_unittest.cc',
'win/scoped_variant_unittest.cc',
'win/win_util_unittest.cc',
+ 'win/wrapped_window_proc_unittest.cc',
],
'dependencies': [
'base',
'base_i18n',
+ 'base_static',
'test_support_base',
'../testing/gmock.gyp:gmock',
'../testing/gtest.gyp:gtest',
@@ -211,7 +247,6 @@
}, { # OS != "linux" and OS != "freebsd" and OS != "openbsd" and OS != "solaris"
'sources!': [
'message_pump_glib_unittest.cc',
- 'crypto/rsa_private_key_nss_unittest.cc',
]
}],
# This is needed to trigger the dll copy step on windows.
@@ -236,11 +271,6 @@
'win_util_unittest.cc',
],
}],
- [ 'use_openssl==1', {
- 'sources!': [
- 'crypto/rsa_private_key_nss_unittest.cc',
- ],
- }],
],
},
{
diff --git a/base/base.gypi b/base/base.gypi
index ef1d8d8..8e49dd5 100644
--- a/base/base.gypi
+++ b/base/base.gypi
@@ -26,6 +26,7 @@
'atomicops.h',
'atomicops_internals_x86_gcc.cc',
'atomicops_internals_x86_msvc.h',
+ 'base_api.h',
'base_paths.cc',
'base_paths.h',
'base_paths_mac.h',
@@ -33,8 +34,6 @@
'base_paths_linux.cc',
'base_paths_win.cc',
'base_paths_win.h',
- 'base_switches.cc',
- 'base_switches.h',
'basictypes.h',
'bind.h',
'bind_helpers.h',
@@ -89,6 +88,11 @@
'file_version_info_mac.mm',
'file_version_info_win.cc',
'file_version_info_win.h',
+ 'files/file_path_watcher.cc',
+ 'files/file_path_watcher.h',
+ 'files/file_path_watcher_linux.cc',
+ 'files/file_path_watcher_mac.cc',
+ 'files/file_path_watcher_win.cc',
'fix_wp64.h',
'float_util.h',
'foundation_utils_mac.h',
@@ -106,13 +110,13 @@
'lazy_instance.cc',
'lazy_instance.h',
'linked_list.h',
- 'linked_ptr.h',
'logging.cc',
'logging.h',
'logging_win.cc',
+ 'logging_win.h',
'mac/cocoa_protocols.h',
- 'mac/foundation_util.h',
- 'mac/foundation_util.mm',
+ 'mac/foundation_util.h',
+ 'mac/foundation_util.mm',
'mac/mac_util.h',
'mac/mac_util.mm',
'mac/os_crash_dumps.cc',
@@ -123,8 +127,27 @@
'mac/scoped_nsautorelease_pool.mm',
'mach_ipc_mac.h',
'mach_ipc_mac.mm',
- 'memory_debug.cc',
- 'memory_debug.h',
+ 'memory/linked_ptr.h',
+ 'memory/memory_debug.cc',
+ 'memory/memory_debug.h',
+ 'memory/raw_scoped_refptr_mismatch_checker.h',
+ 'memory/ref_counted.cc',
+ 'memory/ref_counted.h',
+ 'memory/ref_counted_memory.cc',
+ 'memory/ref_counted_memory.h',
+ 'memory/scoped_callback_factory.h',
+ 'memory/scoped_handle.h',
+ 'memory/scoped_native_library.cc',
+ 'memory/scoped_native_library.h',
+ 'memory/scoped_nsobject.h',
+ 'memory/scoped_open_process.h',
+ 'memory/scoped_ptr.h',
+ 'memory/scoped_temp_dir.cc',
+ 'memory/scoped_temp_dir.h',
+ 'memory/scoped_vector.h',
+ 'memory/singleton.h',
+ 'memory/weak_ptr.cc',
+ 'memory/weak_ptr.h',
'message_loop.cc',
'message_loop.h',
'message_loop_proxy.cc',
@@ -176,32 +199,17 @@
'rand_util.h',
'rand_util_posix.cc',
'rand_util_win.cc',
- 'raw_scoped_refptr_mismatch_checker.h',
- 'ref_counted.cc',
- 'ref_counted.h',
- 'ref_counted_memory.cc',
- 'ref_counted_memory.h',
'resource_util.cc',
'resource_util.h',
'safe_strerror_posix.cc',
'safe_strerror_posix.h',
- 'scoped_callback_factory.h',
- 'scoped_handle.h',
- 'scoped_native_library.cc',
- 'scoped_native_library.h',
- 'scoped_nsobject.h',
- 'scoped_open_process.h',
'scoped_ptr.h',
- 'scoped_temp_dir.cc',
- 'scoped_temp_dir.h',
- 'scoped_vector.h',
'sha1.h',
'sha1_portable.cc',
'sha1_win.cc',
'shared_memory.h',
'shared_memory_posix.cc',
'shared_memory_win.cc',
- 'singleton.h',
'spin_wait.h',
'stack_container.h',
'stl_util-inl.h',
@@ -299,23 +307,21 @@
'utf_string_conversions.h',
'values.cc',
'values.h',
+ 'value_conversions.cc',
+ 'value_conversions.h',
'version.cc',
'version.h',
'vlog.cc',
'vlog.h',
- 'weak_ptr.cc',
- 'weak_ptr.h',
- 'win/i18n.cc',
- 'win/i18n.h',
- 'win/object_watcher.cc',
- 'win/object_watcher.h',
- 'win/pe_image.cc',
'win/event_trace_consumer.h',
'win/event_trace_controller.cc',
'win/event_trace_controller.h',
'win/event_trace_provider.cc',
'win/event_trace_provider.h',
- 'win/pe_image.h',
+ 'win/i18n.cc',
+ 'win/i18n.h',
+ 'win/object_watcher.cc',
+ 'win/object_watcher.h',
'win/registry.cc',
'win/registry.h',
'win/scoped_bstr.cc',
@@ -331,6 +337,8 @@
'win/win_util.h',
'win/windows_version.cc',
'win/windows_version.h',
+ 'win/wrapped_window_proc.cc',
+ 'win/wrapped_window_proc.h',
'nix/xdg_util.h',
'nix/xdg_util.cc',
],
@@ -398,6 +406,14 @@
'debug/trace_event.cc',
],
},],
+ ['OS=="freebsd" or OS=="openbsd"', {
+ 'sources!': [
+ 'base/files/file_path_watcher_linux.cc',
+ ],
+ 'sources': [
+ 'base/files/file_path_watcher_stub.cc',
+ ],
+ }],
],
}],
],
@@ -411,6 +427,7 @@
'base_target': 1,
},
'dependencies': [
+ 'base_static',
'../third_party/modp_b64/modp_b64.gyp:modp_b64',
'third_party/dynamic_annotations/dynamic_annotations.gyp:dynamic_annotations',
],
@@ -439,16 +456,6 @@
},
},
],
- [ 'use_openssl==1', {
- 'dependencies': [
- '../third_party/openssl/openssl.gyp:openssl',
- ],
- }, { # use_openssl==0
- 'dependencies': [
- '../build/linux/system.gyp:nss',
- ],
- }
- ],
],
'dependencies': [
'symbolize',
@@ -502,112 +509,25 @@
'$(SDKROOT)/System/Library/Frameworks/Security.framework',
],
},
- }, { # OS != "mac"
- 'sources!': [
- 'crypto/cssm_init.cc',
- 'crypto/cssm_init.h',
- ],
}],
- [ 'OS == "mac" or OS == "win"', {
- 'dependencies': [
- '../third_party/nss/nss.gyp:nss',
- ],
- },],
[ 'OS != "win"', {
'dependencies': ['../third_party/libevent/libevent.gyp:libevent'],
'sources!': [
'third_party/purify/pure_api.c',
'base_drag_source.cc',
'base_drop_target.cc',
- 'crypto/capi_util.h',
- 'crypto/capi_util.cc',
'event_recorder.cc',
'file_version_info.cc',
- 'pe_image.cc',
'registry.cc',
'resource_util.cc',
'win_util.cc',
],
},],
- [ 'use_openssl==1', {
- # TODO(joth): Use a glob to match exclude patterns once the
- # OpenSSL file set is complete.
- 'sources!': [
- 'crypto/encryptor_nss.cc',
- 'crypto/rsa_private_key_nss.cc',
- 'crypto/secure_hash_default.cc',
- 'crypto/signature_creator_nss.cc',
- 'crypto/signature_verifier_nss.cc',
- 'crypto/symmetric_key_nss.cc',
- 'hmac_nss.cc',
- 'nss_util.cc',
- 'nss_util.h',
- # Note that sha2.cc depends on the NSS files bundled into
- # chromium; it does not have the _nss postfix as it is required
- # on platforms besides linux and *bsd.
- 'sha2.cc',
- 'third_party/nss/blapi.h',
- 'third_party/nss/blapit.h',
- 'third_party/nss/sha256.h',
- 'third_party/nss/sha512.cc',
- ],
- }, {
- 'sources!': [
- 'crypto/encryptor_openssl.cc',
- 'crypto/rsa_private_key_openssl.cc',
- 'crypto/secure_hash_openssl.cc',
- 'crypto/signature_creator_openssl.cc',
- 'crypto/signature_verifier_openssl.cc',
- 'crypto/symmetric_key_openssl.cc',
- 'hmac_openssl.cc',
- 'openssl_util.cc',
- 'openssl_util.h',
- 'sha2_openssl.cc',
- ],
- },],
],
'sources': [
- 'crypto/capi_util.cc',
- 'crypto/capi_util.h',
- 'crypto/crypto_module_blocking_password_delegate.h',
- 'crypto/cssm_init.cc',
- 'crypto/cssm_init.h',
- 'crypto/encryptor.h',
- 'crypto/encryptor_mac.cc',
- 'crypto/encryptor_nss.cc',
- 'crypto/encryptor_openssl.cc',
- 'crypto/encryptor_win.cc',
- 'crypto/rsa_private_key.h',
- 'crypto/rsa_private_key.cc',
- 'crypto/rsa_private_key_mac.cc',
- 'crypto/rsa_private_key_nss.cc',
- 'crypto/rsa_private_key_openssl.cc',
- 'crypto/rsa_private_key_win.cc',
- 'crypto/secure_hash.h',
- 'crypto/secure_hash_default.cc',
- 'crypto/secure_hash_openssl.cc',
- 'crypto/signature_creator.h',
- 'crypto/signature_creator_mac.cc',
- 'crypto/signature_creator_nss.cc',
- 'crypto/signature_creator_openssl.cc',
- 'crypto/signature_creator_win.cc',
- 'crypto/signature_verifier.h',
- 'crypto/signature_verifier_mac.cc',
- 'crypto/signature_verifier_nss.cc',
- 'crypto/signature_verifier_openssl.cc',
- 'crypto/signature_verifier_win.cc',
- 'crypto/symmetric_key.h',
- 'crypto/symmetric_key_mac.cc',
- 'crypto/symmetric_key_nss.cc',
- 'crypto/symmetric_key_openssl.cc',
- 'crypto/symmetric_key_win.cc',
'third_party/nspr/prcpucfg.h',
'third_party/nspr/prcpucfg_win.h',
'third_party/nspr/prtypes.h',
- 'third_party/nss/blapi.h',
- 'third_party/nss/blapit.h',
- 'third_party/nss/sha256.h',
- 'third_party/nss/sha512.cc',
'third_party/purify/pure.h',
'third_party/purify/pure_api.c',
'third_party/xdg_user_dirs/xdg_user_dir_lookup.cc',
@@ -620,11 +540,6 @@
'event_recorder_stubs.cc',
'file_descriptor_shuffle.cc',
'file_descriptor_shuffle.h',
- 'hmac.h',
- 'hmac_mac.cc',
- 'hmac_nss.cc',
- 'hmac_openssl.cc',
- 'hmac_win.cc',
'linux_util.cc',
'linux_util.h',
'md5.cc',
@@ -640,13 +555,6 @@
'message_pump_mac.mm',
'metrics/field_trial.cc',
'metrics/field_trial.h',
- 'nss_util.cc',
- 'nss_util.h',
- 'openssl_util.cc',
- 'openssl_util.h',
- 'sha2.cc',
- 'sha2.h',
- 'sha2_openssl.cc',
'string16.cc',
'string16.h',
'sync_socket.h',
@@ -668,6 +576,7 @@
'base_target': 1,
},
'dependencies': [
+ 'base_static_win64',
'third_party/dynamic_annotations/dynamic_annotations.gyp:dynamic_annotations_win64',
],
# TODO(gregoryd): direct_dependent_settings should be shared with the
diff --git a/base/base64.h b/base/base64.h
index 39cebfb..294fb83 100644
--- a/base/base64.h
+++ b/base/base64.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -8,15 +8,17 @@
#include <string>
+#include "base/base_api.h"
+
namespace base {
// Encodes the input string in base64. Returns true if successful and false
// otherwise. The output string is only modified if successful.
-bool Base64Encode(const std::string& input, std::string* output);
+BASE_API bool Base64Encode(const std::string& input, std::string* output);
// Decodes the base64 input string. Returns true if successful and false
// otherwise. The output string is only modified if successful.
-bool Base64Decode(const std::string& input, std::string* output);
+BASE_API bool Base64Decode(const std::string& input, std::string* output);
} // namespace base
diff --git a/base/base_api.h b/base/base_api.h
new file mode 100644
index 0000000..83b4bdf
--- /dev/null
+++ b/base/base_api.h
@@ -0,0 +1,19 @@
+// Copyright (c) 2011 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 BASE_BASE_API_H_
+#define BASE_BASE_API_H_
+#pragma once
+
+#if defined(WIN32) && defined(BASE_DLL)
+#if defined(BASE_IMPLEMENTATION)
+#define BASE_API __declspec(dllexport)
+#else
+#define BASE_API __declspec(dllimport)
+#endif // defined(BASE_IMPLEMENTATION)
+#else
+#define BASE_API
+#endif
+
+#endif // BASE_BASE_API_H_
diff --git a/base/base_paths.h b/base/base_paths.h
index 72cff15..3c3c8ed 100644
--- a/base/base_paths.h
+++ b/base/base_paths.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -9,7 +9,8 @@
// This file declares path keys for the base module. These can be used with
// the PathService to access various special directories and files.
-#include "base/basictypes.h"
+#include "build/build_config.h"
+
#if defined(OS_WIN)
#include "base/base_paths_win.h"
#elif defined(OS_MACOSX)
diff --git a/base/base_paths_linux.cc b/base/base_paths_linux.cc
index ca8c757..a5fdb12 100644
--- a/base/base_paths_linux.cc
+++ b/base/base_paths_linux.cc
@@ -1,24 +1,26 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
#include "base/base_paths.h"
-#include <unistd.h>
-#if defined(OS_FREEBSD)
-#include <sys/param.h>
-#include <sys/sysctl.h>
-#endif
+#include <ostream>
+#include <string>
+#include "build/build_config.h"
#include "base/environment.h"
#include "base/file_path.h"
#include "base/file_util.h"
#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
#include "base/path_service.h"
-#include "base/scoped_ptr.h"
-#include "base/sys_string_conversions.h"
#include "base/nix/xdg_util.h"
+#if defined(OS_FREEBSD)
+#include <sys/param.h>
+#include <sys/sysctl.h>
+#endif
+
namespace base {
#if defined(OS_LINUX)
diff --git a/base/base_paths_mac.mm b/base/base_paths_mac.mm
index 1210834..ec1398b 100644
--- a/base/base_paths_mac.mm
+++ b/base/base_paths_mac.mm
@@ -53,19 +53,20 @@ bool PathProviderMac(int key, FilePath* result) {
return base::mac::GetUserDirectory(NSApplicationSupportDirectory, result);
case base::DIR_SOURCE_ROOT: {
// Go through PathService to catch overrides.
- if (PathService::Get(base::FILE_EXE, result)) {
- // Start with the executable's directory.
- *result = result->DirName();
- if (base::mac::AmIBundled()) {
- // The bundled app executables (Chromium, TestShell, etc) live five
- // levels down, eg:
- // src/xcodebuild/{Debug|Release}/Chromium.app/Contents/MacOS/Chromium
- *result = result->DirName().DirName().DirName().DirName().DirName();
- } else {
- // Unit tests execute two levels deep from the source root, eg:
- // src/xcodebuild/{Debug|Release}/base_unittests
- *result = result->DirName().DirName();
- }
+ if (!PathService::Get(base::FILE_EXE, result))
+ return false;
+
+ // Start with the executable's directory.
+ *result = result->DirName();
+ if (base::mac::AmIBundled()) {
+ // The bundled app executables (Chromium, TestShell, etc) live five
+ // levels down, eg:
+ // src/xcodebuild/{Debug|Release}/Chromium.app/Contents/MacOS/Chromium
+ *result = result->DirName().DirName().DirName().DirName().DirName();
+ } else {
+ // Unit tests execute two levels deep from the source root, eg:
+ // src/xcodebuild/{Debug|Release}/base_unittests
+ *result = result->DirName().DirName();
}
return true;
}
diff --git a/base/basictypes.h b/base/basictypes.h
index 74c0460..1188d8d 100644
--- a/base/basictypes.h
+++ b/base/basictypes.h
@@ -27,9 +27,12 @@ typedef short int16;
typedef int int32;
#endif
-// The NSPR system headers define 64-bit as |long| when possible. In order to
-// not have typedef mismatches, we do the same on LP64.
-#if __LP64__
+// The NSPR system headers define 64-bit as |long| when possible, except on
+// Mac OS X. In order to not have typedef mismatches, we do the same on LP64.
+//
+// On Mac OS X, |long long| is used for 64-bit types for compatibility with
+// <inttypes.h> format macros even in the LP64 model.
+#if defined(__LP64__) && !defined(OS_MACOSX)
typedef long int64;
#else
typedef long long int64;
@@ -51,7 +54,7 @@ typedef unsigned int uint32;
#endif
// See the comment above about NSPR and 64-bit.
-#if __LP64__
+#if defined(__LP64__) && !defined(OS_MACOSX)
typedef unsigned long uint64;
#else
typedef unsigned long long uint64;
diff --git a/base/bind_helpers.h b/base/bind_helpers.h
index c1ca3d7..3293dbb 100644
--- a/base/bind_helpers.h
+++ b/base/bind_helpers.h
@@ -133,8 +133,17 @@ class SupportsAddRefAndRelease {
void Release();
};
+// MSVC warns when you try to use Base if T has a private destructor, the
+// common pattern for refcounted types. It does this even though no attempt to
+// instantiate Base is made. We disable the warning for this definition.
+#if defined(OS_WIN)
+#pragma warning(disable:4624)
+#endif
struct Base : public T, public BaseMixin {
};
+#if defined(OS_WIN)
+#pragma warning(default:4624)
+#endif
template <void(BaseMixin::*)(void)> struct Helper {};
@@ -161,7 +170,11 @@ struct UnsafeBindtoRefCountedArgHelper<true, T>
};
template <typename T>
-struct UnsafeBindtoRefCountedArg
+struct UnsafeBindtoRefCountedArg : false_type {
+};
+
+template <typename T>
+struct UnsafeBindtoRefCountedArg<T*>
: UnsafeBindtoRefCountedArgHelper<is_class<T>::value, T> {
};
@@ -233,43 +246,6 @@ struct MaybeRefcount<base::true_type, const T*> {
static void Release(const T* o) { o->Release(); }
};
-
-// This is a typetraits object that's used to convert an argument type into a
-// type suitable for storage. In particular, it strips off references, and
-// converts arrays to pointers.
-//
-// This array type becomes an issue because we are passing bound parameters by
-// const reference. In this case, we end up passing an actual array type in the
-// initializer list which C++ does not allow. This will break passing of
-// C-string literals.
-template <typename T>
-struct BindType {
- typedef T StorageType;
-};
-
-// This should almost be impossible to trigger unless someone manually
-// specifies type of the bind parameters. However, in case they do,
-// this will guard against us accidentally storing a reference parameter.
-template <typename T>
-struct BindType<T&> {
- typedef T StorageType;
-};
-
-// Note that for array types, we implicitly add a const in the conversion. This
-// means that it is not possible to bind array arguments to functions that take
-// a non-const pointer. Trying to specialize the template based on a "const
-// T[n]" does not seem to match correctly, so we are stuck with this
-// restriction.
-template <typename T, size_t n>
-struct BindType<T[n]> {
- typedef const T* StorageType;
-};
-
-template <typename T>
-struct BindType<T[]> {
- typedef const T* StorageType;
-};
-
} // namespace internal
template <typename T>
diff --git a/base/bind_internal.h b/base/bind_internal.h
index bb5f46f..606e2b0 100644
--- a/base/bind_internal.h
+++ b/base/bind_internal.h
@@ -3,6 +3,7 @@
// DO NOT EDIT BY HAND!!!
+
// Copyright (c) 2011 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.
@@ -73,6 +74,7 @@ template <typename R>
struct FunctionTraits<R(*)()> {
typedef R (*NormalizedSig)();
typedef false_type IsMethod;
+
};
// Method: Arity 0.
@@ -80,6 +82,10 @@ template <typename R, typename T>
struct FunctionTraits<R(T::*)()> {
typedef R (T::*NormalizedSig)();
typedef true_type IsMethod;
+
+ // Target type for each bound parameter.
+ typedef T B1;
+
};
// Const Method: Arity 0.
@@ -87,6 +93,10 @@ template <typename R, typename T>
struct FunctionTraits<R(T::*)() const> {
typedef R (T::*NormalizedSig)();
typedef true_type IsMethod;
+
+ // Target type for each bound parameter.
+ typedef T B1;
+
};
// Function: Arity 1.
@@ -94,6 +104,9 @@ template <typename R, typename X1>
struct FunctionTraits<R(*)(X1)> {
typedef R (*NormalizedSig)(X1);
typedef false_type IsMethod;
+ // Target type for each bound parameter.
+ typedef X1 B1;
+
};
// Method: Arity 1.
@@ -101,6 +114,11 @@ template <typename R, typename T, typename X1>
struct FunctionTraits<R(T::*)(X1)> {
typedef R (T::*NormalizedSig)(X1);
typedef true_type IsMethod;
+
+ // Target type for each bound parameter.
+ typedef T B1;
+ typedef X1 B2;
+
};
// Const Method: Arity 1.
@@ -108,6 +126,11 @@ template <typename R, typename T, typename X1>
struct FunctionTraits<R(T::*)(X1) const> {
typedef R (T::*NormalizedSig)(X1);
typedef true_type IsMethod;
+
+ // Target type for each bound parameter.
+ typedef T B1;
+ typedef X1 B2;
+
};
// Function: Arity 2.
@@ -115,6 +138,10 @@ template <typename R, typename X1, typename X2>
struct FunctionTraits<R(*)(X1, X2)> {
typedef R (*NormalizedSig)(X1, X2);
typedef false_type IsMethod;
+ // Target type for each bound parameter.
+ typedef X1 B1;
+ typedef X2 B2;
+
};
// Method: Arity 2.
@@ -122,6 +149,12 @@ template <typename R, typename T, typename X1, typename X2>
struct FunctionTraits<R(T::*)(X1, X2)> {
typedef R (T::*NormalizedSig)(X1, X2);
typedef true_type IsMethod;
+
+ // Target type for each bound parameter.
+ typedef T B1;
+ typedef X1 B2;
+ typedef X2 B3;
+
};
// Const Method: Arity 2.
@@ -129,6 +162,12 @@ template <typename R, typename T, typename X1, typename X2>
struct FunctionTraits<R(T::*)(X1, X2) const> {
typedef R (T::*NormalizedSig)(X1, X2);
typedef true_type IsMethod;
+
+ // Target type for each bound parameter.
+ typedef T B1;
+ typedef X1 B2;
+ typedef X2 B3;
+
};
// Function: Arity 3.
@@ -136,6 +175,11 @@ template <typename R, typename X1, typename X2, typename X3>
struct FunctionTraits<R(*)(X1, X2, X3)> {
typedef R (*NormalizedSig)(X1, X2, X3);
typedef false_type IsMethod;
+ // Target type for each bound parameter.
+ typedef X1 B1;
+ typedef X2 B2;
+ typedef X3 B3;
+
};
// Method: Arity 3.
@@ -143,6 +187,13 @@ template <typename R, typename T, typename X1, typename X2, typename X3>
struct FunctionTraits<R(T::*)(X1, X2, X3)> {
typedef R (T::*NormalizedSig)(X1, X2, X3);
typedef true_type IsMethod;
+
+ // Target type for each bound parameter.
+ typedef T B1;
+ typedef X1 B2;
+ typedef X2 B3;
+ typedef X3 B4;
+
};
// Const Method: Arity 3.
@@ -150,6 +201,13 @@ template <typename R, typename T, typename X1, typename X2, typename X3>
struct FunctionTraits<R(T::*)(X1, X2, X3) const> {
typedef R (T::*NormalizedSig)(X1, X2, X3);
typedef true_type IsMethod;
+
+ // Target type for each bound parameter.
+ typedef T B1;
+ typedef X1 B2;
+ typedef X2 B3;
+ typedef X3 B4;
+
};
// Function: Arity 4.
@@ -157,6 +215,12 @@ template <typename R, typename X1, typename X2, typename X3, typename X4>
struct FunctionTraits<R(*)(X1, X2, X3, X4)> {
typedef R (*NormalizedSig)(X1, X2, X3, X4);
typedef false_type IsMethod;
+ // Target type for each bound parameter.
+ typedef X1 B1;
+ typedef X2 B2;
+ typedef X3 B3;
+ typedef X4 B4;
+
};
// Method: Arity 4.
@@ -165,6 +229,14 @@ template <typename R, typename T, typename X1, typename X2, typename X3,
struct FunctionTraits<R(T::*)(X1, X2, X3, X4)> {
typedef R (T::*NormalizedSig)(X1, X2, X3, X4);
typedef true_type IsMethod;
+
+ // Target type for each bound parameter.
+ typedef T B1;
+ typedef X1 B2;
+ typedef X2 B3;
+ typedef X3 B4;
+ typedef X4 B5;
+
};
// Const Method: Arity 4.
@@ -173,6 +245,14 @@ template <typename R, typename T, typename X1, typename X2, typename X3,
struct FunctionTraits<R(T::*)(X1, X2, X3, X4) const> {
typedef R (T::*NormalizedSig)(X1, X2, X3, X4);
typedef true_type IsMethod;
+
+ // Target type for each bound parameter.
+ typedef T B1;
+ typedef X1 B2;
+ typedef X2 B3;
+ typedef X3 B4;
+ typedef X4 B5;
+
};
// Function: Arity 5.
@@ -181,6 +261,13 @@ template <typename R, typename X1, typename X2, typename X3, typename X4,
struct FunctionTraits<R(*)(X1, X2, X3, X4, X5)> {
typedef R (*NormalizedSig)(X1, X2, X3, X4, X5);
typedef false_type IsMethod;
+ // Target type for each bound parameter.
+ typedef X1 B1;
+ typedef X2 B2;
+ typedef X3 B3;
+ typedef X4 B4;
+ typedef X5 B5;
+
};
// Method: Arity 5.
@@ -189,6 +276,15 @@ template <typename R, typename T, typename X1, typename X2, typename X3,
struct FunctionTraits<R(T::*)(X1, X2, X3, X4, X5)> {
typedef R (T::*NormalizedSig)(X1, X2, X3, X4, X5);
typedef true_type IsMethod;
+
+ // Target type for each bound parameter.
+ typedef T B1;
+ typedef X1 B2;
+ typedef X2 B3;
+ typedef X3 B4;
+ typedef X4 B5;
+ typedef X5 B6;
+
};
// Const Method: Arity 5.
@@ -197,6 +293,15 @@ template <typename R, typename T, typename X1, typename X2, typename X3,
struct FunctionTraits<R(T::*)(X1, X2, X3, X4, X5) const> {
typedef R (T::*NormalizedSig)(X1, X2, X3, X4, X5);
typedef true_type IsMethod;
+
+ // Target type for each bound parameter.
+ typedef T B1;
+ typedef X1 B2;
+ typedef X2 B3;
+ typedef X3 B4;
+ typedef X4 B5;
+ typedef X5 B6;
+
};
// Function: Arity 6.
@@ -205,6 +310,14 @@ template <typename R, typename X1, typename X2, typename X3, typename X4,
struct FunctionTraits<R(*)(X1, X2, X3, X4, X5, X6)> {
typedef R (*NormalizedSig)(X1, X2, X3, X4, X5, X6);
typedef false_type IsMethod;
+ // Target type for each bound parameter.
+ typedef X1 B1;
+ typedef X2 B2;
+ typedef X3 B3;
+ typedef X4 B4;
+ typedef X5 B5;
+ typedef X6 B6;
+
};
// Method: Arity 6.
@@ -213,6 +326,16 @@ template <typename R, typename T, typename X1, typename X2, typename X3,
struct FunctionTraits<R(T::*)(X1, X2, X3, X4, X5, X6)> {
typedef R (T::*NormalizedSig)(X1, X2, X3, X4, X5, X6);
typedef true_type IsMethod;
+
+ // Target type for each bound parameter.
+ typedef T B1;
+ typedef X1 B2;
+ typedef X2 B3;
+ typedef X3 B4;
+ typedef X4 B5;
+ typedef X5 B6;
+ typedef X6 B7;
+
};
// Const Method: Arity 6.
@@ -221,6 +344,16 @@ template <typename R, typename T, typename X1, typename X2, typename X3,
struct FunctionTraits<R(T::*)(X1, X2, X3, X4, X5, X6) const> {
typedef R (T::*NormalizedSig)(X1, X2, X3, X4, X5, X6);
typedef true_type IsMethod;
+
+ // Target type for each bound parameter.
+ typedef T B1;
+ typedef X1 B2;
+ typedef X2 B3;
+ typedef X3 B4;
+ typedef X4 B5;
+ typedef X5 B6;
+ typedef X6 B7;
+
};
// InvokerN<>
@@ -258,11 +391,8 @@ struct Invoker0<StorageType, R(*)()> {
// Function: Arity 1 -> 1.
template <typename StorageType, typename R,typename X1>
struct Invoker0<StorageType, R(*)(X1)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
- static R DoInvoke(InvokerStorageBase* base, const X1& x1) {
+ static R DoInvoke(InvokerStorageBase* base,
+ typename internal::ParamTraits<X1>::ForwardType x1) {
StorageType* invoker = static_cast<StorageType*>(base);
return invoker->f_(x1);
}
@@ -271,12 +401,9 @@ struct Invoker0<StorageType, R(*)(X1)> {
// Function: Arity 2 -> 2.
template <typename StorageType, typename R,typename X1, typename X2>
struct Invoker0<StorageType, R(*)(X1, X2)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
- static R DoInvoke(InvokerStorageBase* base, const X1& x1, const X2& x2) {
+ static R DoInvoke(InvokerStorageBase* base,
+ typename internal::ParamTraits<X1>::ForwardType x1,
+ typename internal::ParamTraits<X2>::ForwardType x2) {
StorageType* invoker = static_cast<StorageType*>(base);
return invoker->f_(x1, x2);
}
@@ -286,14 +413,10 @@ struct Invoker0<StorageType, R(*)(X1, X2)> {
template <typename StorageType, typename R,typename X1, typename X2,
typename X3>
struct Invoker0<StorageType, R(*)(X1, X2, X3)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ||
- is_non_const_reference<X3>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
- static R DoInvoke(InvokerStorageBase* base, const X1& x1, const X2& x2,
- const X3& x3) {
+ static R DoInvoke(InvokerStorageBase* base,
+ typename internal::ParamTraits<X1>::ForwardType x1,
+ typename internal::ParamTraits<X2>::ForwardType x2,
+ typename internal::ParamTraits<X3>::ForwardType x3) {
StorageType* invoker = static_cast<StorageType*>(base);
return invoker->f_(x1, x2, x3);
}
@@ -303,15 +426,11 @@ struct Invoker0<StorageType, R(*)(X1, X2, X3)> {
template <typename StorageType, typename R,typename X1, typename X2,
typename X3, typename X4>
struct Invoker0<StorageType, R(*)(X1, X2, X3, X4)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ||
- is_non_const_reference<X3>::value ||
- is_non_const_reference<X4>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
- static R DoInvoke(InvokerStorageBase* base, const X1& x1, const X2& x2,
- const X3& x3, const X4& x4) {
+ static R DoInvoke(InvokerStorageBase* base,
+ typename internal::ParamTraits<X1>::ForwardType x1,
+ typename internal::ParamTraits<X2>::ForwardType x2,
+ typename internal::ParamTraits<X3>::ForwardType x3,
+ typename internal::ParamTraits<X4>::ForwardType x4) {
StorageType* invoker = static_cast<StorageType*>(base);
return invoker->f_(x1, x2, x3, x4);
}
@@ -321,16 +440,12 @@ struct Invoker0<StorageType, R(*)(X1, X2, X3, X4)> {
template <typename StorageType, typename R,typename X1, typename X2,
typename X3, typename X4, typename X5>
struct Invoker0<StorageType, R(*)(X1, X2, X3, X4, X5)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ||
- is_non_const_reference<X3>::value ||
- is_non_const_reference<X4>::value ||
- is_non_const_reference<X5>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
- static R DoInvoke(InvokerStorageBase* base, const X1& x1, const X2& x2,
- const X3& x3, const X4& x4, const X5& x5) {
+ static R DoInvoke(InvokerStorageBase* base,
+ typename internal::ParamTraits<X1>::ForwardType x1,
+ typename internal::ParamTraits<X2>::ForwardType x2,
+ typename internal::ParamTraits<X3>::ForwardType x3,
+ typename internal::ParamTraits<X4>::ForwardType x4,
+ typename internal::ParamTraits<X5>::ForwardType x5) {
StorageType* invoker = static_cast<StorageType*>(base);
return invoker->f_(x1, x2, x3, x4, x5);
}
@@ -340,17 +455,13 @@ struct Invoker0<StorageType, R(*)(X1, X2, X3, X4, X5)> {
template <typename StorageType, typename R,typename X1, typename X2,
typename X3, typename X4, typename X5, typename X6>
struct Invoker0<StorageType, R(*)(X1, X2, X3, X4, X5, X6)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ||
- is_non_const_reference<X3>::value ||
- is_non_const_reference<X4>::value ||
- is_non_const_reference<X5>::value ||
- is_non_const_reference<X6>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
- static R DoInvoke(InvokerStorageBase* base, const X1& x1, const X2& x2,
- const X3& x3, const X4& x4, const X5& x5, const X6& x6) {
+ static R DoInvoke(InvokerStorageBase* base,
+ typename internal::ParamTraits<X1>::ForwardType x1,
+ typename internal::ParamTraits<X2>::ForwardType x2,
+ typename internal::ParamTraits<X3>::ForwardType x3,
+ typename internal::ParamTraits<X4>::ForwardType x4,
+ typename internal::ParamTraits<X5>::ForwardType x5,
+ typename internal::ParamTraits<X6>::ForwardType x6) {
StorageType* invoker = static_cast<StorageType*>(base);
return invoker->f_(x1, x2, x3, x4, x5, x6);
}
@@ -362,10 +473,6 @@ struct Invoker1;
// Function: Arity 1 -> 0.
template <typename StorageType, typename R,typename X1>
struct Invoker1<StorageType, R(*)(X1)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
static R DoInvoke(InvokerStorageBase* base) {
StorageType* invoker = static_cast<StorageType*>(base);
return invoker->f_(Unwrap(invoker->p1_));
@@ -384,12 +491,8 @@ struct Invoker1<StorageType, R(T::*)()> {
// Function: Arity 2 -> 1.
template <typename StorageType, typename R,typename X1, typename X2>
struct Invoker1<StorageType, R(*)(X1, X2)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
- static R DoInvoke(InvokerStorageBase* base, const X2& x2) {
+ static R DoInvoke(InvokerStorageBase* base,
+ typename internal::ParamTraits<X2>::ForwardType x2) {
StorageType* invoker = static_cast<StorageType*>(base);
return invoker->f_(Unwrap(invoker->p1_), x2);
}
@@ -398,11 +501,8 @@ struct Invoker1<StorageType, R(*)(X1, X2)> {
// Method: Arity 1 -> 1.
template <typename StorageType, typename R, typename T, typename X1>
struct Invoker1<StorageType, R(T::*)(X1)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
- static R DoInvoke(InvokerStorageBase* base, const X1& x1) {
+ static R DoInvoke(InvokerStorageBase* base,
+ typename internal::ParamTraits<X1>::ForwardType x1) {
StorageType* invoker = static_cast<StorageType*>(base);
return (Unwrap(invoker->p1_)->*invoker->f_)(x1);
}
@@ -412,13 +512,9 @@ struct Invoker1<StorageType, R(T::*)(X1)> {
template <typename StorageType, typename R,typename X1, typename X2,
typename X3>
struct Invoker1<StorageType, R(*)(X1, X2, X3)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ||
- is_non_const_reference<X3>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
- static R DoInvoke(InvokerStorageBase* base, const X2& x2, const X3& x3) {
+ static R DoInvoke(InvokerStorageBase* base,
+ typename internal::ParamTraits<X2>::ForwardType x2,
+ typename internal::ParamTraits<X3>::ForwardType x3) {
StorageType* invoker = static_cast<StorageType*>(base);
return invoker->f_(Unwrap(invoker->p1_), x2, x3);
}
@@ -428,12 +524,9 @@ struct Invoker1<StorageType, R(*)(X1, X2, X3)> {
template <typename StorageType, typename R, typename T, typename X1,
typename X2>
struct Invoker1<StorageType, R(T::*)(X1, X2)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
- static R DoInvoke(InvokerStorageBase* base, const X1& x1, const X2& x2) {
+ static R DoInvoke(InvokerStorageBase* base,
+ typename internal::ParamTraits<X1>::ForwardType x1,
+ typename internal::ParamTraits<X2>::ForwardType x2) {
StorageType* invoker = static_cast<StorageType*>(base);
return (Unwrap(invoker->p1_)->*invoker->f_)(x1, x2);
}
@@ -443,15 +536,10 @@ struct Invoker1<StorageType, R(T::*)(X1, X2)> {
template <typename StorageType, typename R,typename X1, typename X2,
typename X3, typename X4>
struct Invoker1<StorageType, R(*)(X1, X2, X3, X4)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ||
- is_non_const_reference<X3>::value ||
- is_non_const_reference<X4>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
- static R DoInvoke(InvokerStorageBase* base, const X2& x2, const X3& x3,
- const X4& x4) {
+ static R DoInvoke(InvokerStorageBase* base,
+ typename internal::ParamTraits<X2>::ForwardType x2,
+ typename internal::ParamTraits<X3>::ForwardType x3,
+ typename internal::ParamTraits<X4>::ForwardType x4) {
StorageType* invoker = static_cast<StorageType*>(base);
return invoker->f_(Unwrap(invoker->p1_), x2, x3, x4);
}
@@ -461,14 +549,10 @@ struct Invoker1<StorageType, R(*)(X1, X2, X3, X4)> {
template <typename StorageType, typename R, typename T, typename X1,
typename X2, typename X3>
struct Invoker1<StorageType, R(T::*)(X1, X2, X3)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ||
- is_non_const_reference<X3>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
- static R DoInvoke(InvokerStorageBase* base, const X1& x1, const X2& x2,
- const X3& x3) {
+ static R DoInvoke(InvokerStorageBase* base,
+ typename internal::ParamTraits<X1>::ForwardType x1,
+ typename internal::ParamTraits<X2>::ForwardType x2,
+ typename internal::ParamTraits<X3>::ForwardType x3) {
StorageType* invoker = static_cast<StorageType*>(base);
return (Unwrap(invoker->p1_)->*invoker->f_)(x1, x2, x3);
}
@@ -478,16 +562,11 @@ struct Invoker1<StorageType, R(T::*)(X1, X2, X3)> {
template <typename StorageType, typename R,typename X1, typename X2,
typename X3, typename X4, typename X5>
struct Invoker1<StorageType, R(*)(X1, X2, X3, X4, X5)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ||
- is_non_const_reference<X3>::value ||
- is_non_const_reference<X4>::value ||
- is_non_const_reference<X5>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
- static R DoInvoke(InvokerStorageBase* base, const X2& x2, const X3& x3,
- const X4& x4, const X5& x5) {
+ static R DoInvoke(InvokerStorageBase* base,
+ typename internal::ParamTraits<X2>::ForwardType x2,
+ typename internal::ParamTraits<X3>::ForwardType x3,
+ typename internal::ParamTraits<X4>::ForwardType x4,
+ typename internal::ParamTraits<X5>::ForwardType x5) {
StorageType* invoker = static_cast<StorageType*>(base);
return invoker->f_(Unwrap(invoker->p1_), x2, x3, x4, x5);
}
@@ -497,15 +576,11 @@ struct Invoker1<StorageType, R(*)(X1, X2, X3, X4, X5)> {
template <typename StorageType, typename R, typename T, typename X1,
typename X2, typename X3, typename X4>
struct Invoker1<StorageType, R(T::*)(X1, X2, X3, X4)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ||
- is_non_const_reference<X3>::value ||
- is_non_const_reference<X4>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
- static R DoInvoke(InvokerStorageBase* base, const X1& x1, const X2& x2,
- const X3& x3, const X4& x4) {
+ static R DoInvoke(InvokerStorageBase* base,
+ typename internal::ParamTraits<X1>::ForwardType x1,
+ typename internal::ParamTraits<X2>::ForwardType x2,
+ typename internal::ParamTraits<X3>::ForwardType x3,
+ typename internal::ParamTraits<X4>::ForwardType x4) {
StorageType* invoker = static_cast<StorageType*>(base);
return (Unwrap(invoker->p1_)->*invoker->f_)(x1, x2, x3, x4);
}
@@ -515,17 +590,12 @@ struct Invoker1<StorageType, R(T::*)(X1, X2, X3, X4)> {
template <typename StorageType, typename R,typename X1, typename X2,
typename X3, typename X4, typename X5, typename X6>
struct Invoker1<StorageType, R(*)(X1, X2, X3, X4, X5, X6)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ||
- is_non_const_reference<X3>::value ||
- is_non_const_reference<X4>::value ||
- is_non_const_reference<X5>::value ||
- is_non_const_reference<X6>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
- static R DoInvoke(InvokerStorageBase* base, const X2& x2, const X3& x3,
- const X4& x4, const X5& x5, const X6& x6) {
+ static R DoInvoke(InvokerStorageBase* base,
+ typename internal::ParamTraits<X2>::ForwardType x2,
+ typename internal::ParamTraits<X3>::ForwardType x3,
+ typename internal::ParamTraits<X4>::ForwardType x4,
+ typename internal::ParamTraits<X5>::ForwardType x5,
+ typename internal::ParamTraits<X6>::ForwardType x6) {
StorageType* invoker = static_cast<StorageType*>(base);
return invoker->f_(Unwrap(invoker->p1_), x2, x3, x4, x5, x6);
}
@@ -535,16 +605,12 @@ struct Invoker1<StorageType, R(*)(X1, X2, X3, X4, X5, X6)> {
template <typename StorageType, typename R, typename T, typename X1,
typename X2, typename X3, typename X4, typename X5>
struct Invoker1<StorageType, R(T::*)(X1, X2, X3, X4, X5)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ||
- is_non_const_reference<X3>::value ||
- is_non_const_reference<X4>::value ||
- is_non_const_reference<X5>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
- static R DoInvoke(InvokerStorageBase* base, const X1& x1, const X2& x2,
- const X3& x3, const X4& x4, const X5& x5) {
+ static R DoInvoke(InvokerStorageBase* base,
+ typename internal::ParamTraits<X1>::ForwardType x1,
+ typename internal::ParamTraits<X2>::ForwardType x2,
+ typename internal::ParamTraits<X3>::ForwardType x3,
+ typename internal::ParamTraits<X4>::ForwardType x4,
+ typename internal::ParamTraits<X5>::ForwardType x5) {
StorageType* invoker = static_cast<StorageType*>(base);
return (Unwrap(invoker->p1_)->*invoker->f_)(x1, x2, x3, x4, x5);
}
@@ -556,11 +622,6 @@ struct Invoker2;
// Function: Arity 2 -> 0.
template <typename StorageType, typename R,typename X1, typename X2>
struct Invoker2<StorageType, R(*)(X1, X2)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
static R DoInvoke(InvokerStorageBase* base) {
StorageType* invoker = static_cast<StorageType*>(base);
return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_));
@@ -570,10 +631,6 @@ struct Invoker2<StorageType, R(*)(X1, X2)> {
// Method: Arity 1 -> 0.
template <typename StorageType, typename R, typename T, typename X1>
struct Invoker2<StorageType, R(T::*)(X1)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
static R DoInvoke(InvokerStorageBase* base) {
StorageType* invoker = static_cast<StorageType*>(base);
return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_));
@@ -584,13 +641,8 @@ struct Invoker2<StorageType, R(T::*)(X1)> {
template <typename StorageType, typename R,typename X1, typename X2,
typename X3>
struct Invoker2<StorageType, R(*)(X1, X2, X3)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ||
- is_non_const_reference<X3>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
- static R DoInvoke(InvokerStorageBase* base, const X3& x3) {
+ static R DoInvoke(InvokerStorageBase* base,
+ typename internal::ParamTraits<X3>::ForwardType x3) {
StorageType* invoker = static_cast<StorageType*>(base);
return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_), x3);
}
@@ -600,12 +652,8 @@ struct Invoker2<StorageType, R(*)(X1, X2, X3)> {
template <typename StorageType, typename R, typename T, typename X1,
typename X2>
struct Invoker2<StorageType, R(T::*)(X1, X2)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
- static R DoInvoke(InvokerStorageBase* base, const X2& x2) {
+ static R DoInvoke(InvokerStorageBase* base,
+ typename internal::ParamTraits<X2>::ForwardType x2) {
StorageType* invoker = static_cast<StorageType*>(base);
return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_), x2);
}
@@ -615,14 +663,9 @@ struct Invoker2<StorageType, R(T::*)(X1, X2)> {
template <typename StorageType, typename R,typename X1, typename X2,
typename X3, typename X4>
struct Invoker2<StorageType, R(*)(X1, X2, X3, X4)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ||
- is_non_const_reference<X3>::value ||
- is_non_const_reference<X4>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
- static R DoInvoke(InvokerStorageBase* base, const X3& x3, const X4& x4) {
+ static R DoInvoke(InvokerStorageBase* base,
+ typename internal::ParamTraits<X3>::ForwardType x3,
+ typename internal::ParamTraits<X4>::ForwardType x4) {
StorageType* invoker = static_cast<StorageType*>(base);
return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_), x3, x4);
}
@@ -632,13 +675,9 @@ struct Invoker2<StorageType, R(*)(X1, X2, X3, X4)> {
template <typename StorageType, typename R, typename T, typename X1,
typename X2, typename X3>
struct Invoker2<StorageType, R(T::*)(X1, X2, X3)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ||
- is_non_const_reference<X3>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
- static R DoInvoke(InvokerStorageBase* base, const X2& x2, const X3& x3) {
+ static R DoInvoke(InvokerStorageBase* base,
+ typename internal::ParamTraits<X2>::ForwardType x2,
+ typename internal::ParamTraits<X3>::ForwardType x3) {
StorageType* invoker = static_cast<StorageType*>(base);
return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_), x2, x3);
}
@@ -648,16 +687,10 @@ struct Invoker2<StorageType, R(T::*)(X1, X2, X3)> {
template <typename StorageType, typename R,typename X1, typename X2,
typename X3, typename X4, typename X5>
struct Invoker2<StorageType, R(*)(X1, X2, X3, X4, X5)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ||
- is_non_const_reference<X3>::value ||
- is_non_const_reference<X4>::value ||
- is_non_const_reference<X5>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
- static R DoInvoke(InvokerStorageBase* base, const X3& x3, const X4& x4,
- const X5& x5) {
+ static R DoInvoke(InvokerStorageBase* base,
+ typename internal::ParamTraits<X3>::ForwardType x3,
+ typename internal::ParamTraits<X4>::ForwardType x4,
+ typename internal::ParamTraits<X5>::ForwardType x5) {
StorageType* invoker = static_cast<StorageType*>(base);
return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_), x3, x4, x5);
}
@@ -667,15 +700,10 @@ struct Invoker2<StorageType, R(*)(X1, X2, X3, X4, X5)> {
template <typename StorageType, typename R, typename T, typename X1,
typename X2, typename X3, typename X4>
struct Invoker2<StorageType, R(T::*)(X1, X2, X3, X4)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ||
- is_non_const_reference<X3>::value ||
- is_non_const_reference<X4>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
- static R DoInvoke(InvokerStorageBase* base, const X2& x2, const X3& x3,
- const X4& x4) {
+ static R DoInvoke(InvokerStorageBase* base,
+ typename internal::ParamTraits<X2>::ForwardType x2,
+ typename internal::ParamTraits<X3>::ForwardType x3,
+ typename internal::ParamTraits<X4>::ForwardType x4) {
StorageType* invoker = static_cast<StorageType*>(base);
return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_), x2, x3,
x4);
@@ -686,17 +714,11 @@ struct Invoker2<StorageType, R(T::*)(X1, X2, X3, X4)> {
template <typename StorageType, typename R,typename X1, typename X2,
typename X3, typename X4, typename X5, typename X6>
struct Invoker2<StorageType, R(*)(X1, X2, X3, X4, X5, X6)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ||
- is_non_const_reference<X3>::value ||
- is_non_const_reference<X4>::value ||
- is_non_const_reference<X5>::value ||
- is_non_const_reference<X6>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
- static R DoInvoke(InvokerStorageBase* base, const X3& x3, const X4& x4,
- const X5& x5, const X6& x6) {
+ static R DoInvoke(InvokerStorageBase* base,
+ typename internal::ParamTraits<X3>::ForwardType x3,
+ typename internal::ParamTraits<X4>::ForwardType x4,
+ typename internal::ParamTraits<X5>::ForwardType x5,
+ typename internal::ParamTraits<X6>::ForwardType x6) {
StorageType* invoker = static_cast<StorageType*>(base);
return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_), x3, x4, x5,
x6);
@@ -707,16 +729,11 @@ struct Invoker2<StorageType, R(*)(X1, X2, X3, X4, X5, X6)> {
template <typename StorageType, typename R, typename T, typename X1,
typename X2, typename X3, typename X4, typename X5>
struct Invoker2<StorageType, R(T::*)(X1, X2, X3, X4, X5)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ||
- is_non_const_reference<X3>::value ||
- is_non_const_reference<X4>::value ||
- is_non_const_reference<X5>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
- static R DoInvoke(InvokerStorageBase* base, const X2& x2, const X3& x3,
- const X4& x4, const X5& x5) {
+ static R DoInvoke(InvokerStorageBase* base,
+ typename internal::ParamTraits<X2>::ForwardType x2,
+ typename internal::ParamTraits<X3>::ForwardType x3,
+ typename internal::ParamTraits<X4>::ForwardType x4,
+ typename internal::ParamTraits<X5>::ForwardType x5) {
StorageType* invoker = static_cast<StorageType*>(base);
return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_), x2, x3,
x4, x5);
@@ -730,12 +747,6 @@ struct Invoker3;
template <typename StorageType, typename R,typename X1, typename X2,
typename X3>
struct Invoker3<StorageType, R(*)(X1, X2, X3)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ||
- is_non_const_reference<X3>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
static R DoInvoke(InvokerStorageBase* base) {
StorageType* invoker = static_cast<StorageType*>(base);
return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_),
@@ -747,11 +758,6 @@ struct Invoker3<StorageType, R(*)(X1, X2, X3)> {
template <typename StorageType, typename R, typename T, typename X1,
typename X2>
struct Invoker3<StorageType, R(T::*)(X1, X2)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
static R DoInvoke(InvokerStorageBase* base) {
StorageType* invoker = static_cast<StorageType*>(base);
return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_),
@@ -763,14 +769,8 @@ struct Invoker3<StorageType, R(T::*)(X1, X2)> {
template <typename StorageType, typename R,typename X1, typename X2,
typename X3, typename X4>
struct Invoker3<StorageType, R(*)(X1, X2, X3, X4)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ||
- is_non_const_reference<X3>::value ||
- is_non_const_reference<X4>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
- static R DoInvoke(InvokerStorageBase* base, const X4& x4) {
+ static R DoInvoke(InvokerStorageBase* base,
+ typename internal::ParamTraits<X4>::ForwardType x4) {
StorageType* invoker = static_cast<StorageType*>(base);
return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_),
Unwrap(invoker->p3_), x4);
@@ -781,13 +781,8 @@ struct Invoker3<StorageType, R(*)(X1, X2, X3, X4)> {
template <typename StorageType, typename R, typename T, typename X1,
typename X2, typename X3>
struct Invoker3<StorageType, R(T::*)(X1, X2, X3)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ||
- is_non_const_reference<X3>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
- static R DoInvoke(InvokerStorageBase* base, const X3& x3) {
+ static R DoInvoke(InvokerStorageBase* base,
+ typename internal::ParamTraits<X3>::ForwardType x3) {
StorageType* invoker = static_cast<StorageType*>(base);
return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_),
Unwrap(invoker->p3_), x3);
@@ -798,15 +793,9 @@ struct Invoker3<StorageType, R(T::*)(X1, X2, X3)> {
template <typename StorageType, typename R,typename X1, typename X2,
typename X3, typename X4, typename X5>
struct Invoker3<StorageType, R(*)(X1, X2, X3, X4, X5)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ||
- is_non_const_reference<X3>::value ||
- is_non_const_reference<X4>::value ||
- is_non_const_reference<X5>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
- static R DoInvoke(InvokerStorageBase* base, const X4& x4, const X5& x5) {
+ static R DoInvoke(InvokerStorageBase* base,
+ typename internal::ParamTraits<X4>::ForwardType x4,
+ typename internal::ParamTraits<X5>::ForwardType x5) {
StorageType* invoker = static_cast<StorageType*>(base);
return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_),
Unwrap(invoker->p3_), x4, x5);
@@ -817,14 +806,9 @@ struct Invoker3<StorageType, R(*)(X1, X2, X3, X4, X5)> {
template <typename StorageType, typename R, typename T, typename X1,
typename X2, typename X3, typename X4>
struct Invoker3<StorageType, R(T::*)(X1, X2, X3, X4)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ||
- is_non_const_reference<X3>::value ||
- is_non_const_reference<X4>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
- static R DoInvoke(InvokerStorageBase* base, const X3& x3, const X4& x4) {
+ static R DoInvoke(InvokerStorageBase* base,
+ typename internal::ParamTraits<X3>::ForwardType x3,
+ typename internal::ParamTraits<X4>::ForwardType x4) {
StorageType* invoker = static_cast<StorageType*>(base);
return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_),
Unwrap(invoker->p3_), x3, x4);
@@ -835,17 +819,10 @@ struct Invoker3<StorageType, R(T::*)(X1, X2, X3, X4)> {
template <typename StorageType, typename R,typename X1, typename X2,
typename X3, typename X4, typename X5, typename X6>
struct Invoker3<StorageType, R(*)(X1, X2, X3, X4, X5, X6)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ||
- is_non_const_reference<X3>::value ||
- is_non_const_reference<X4>::value ||
- is_non_const_reference<X5>::value ||
- is_non_const_reference<X6>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
- static R DoInvoke(InvokerStorageBase* base, const X4& x4, const X5& x5,
- const X6& x6) {
+ static R DoInvoke(InvokerStorageBase* base,
+ typename internal::ParamTraits<X4>::ForwardType x4,
+ typename internal::ParamTraits<X5>::ForwardType x5,
+ typename internal::ParamTraits<X6>::ForwardType x6) {
StorageType* invoker = static_cast<StorageType*>(base);
return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_),
Unwrap(invoker->p3_), x4, x5, x6);
@@ -856,16 +833,10 @@ struct Invoker3<StorageType, R(*)(X1, X2, X3, X4, X5, X6)> {
template <typename StorageType, typename R, typename T, typename X1,
typename X2, typename X3, typename X4, typename X5>
struct Invoker3<StorageType, R(T::*)(X1, X2, X3, X4, X5)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ||
- is_non_const_reference<X3>::value ||
- is_non_const_reference<X4>::value ||
- is_non_const_reference<X5>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
- static R DoInvoke(InvokerStorageBase* base, const X3& x3, const X4& x4,
- const X5& x5) {
+ static R DoInvoke(InvokerStorageBase* base,
+ typename internal::ParamTraits<X3>::ForwardType x3,
+ typename internal::ParamTraits<X4>::ForwardType x4,
+ typename internal::ParamTraits<X5>::ForwardType x5) {
StorageType* invoker = static_cast<StorageType*>(base);
return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_),
Unwrap(invoker->p3_), x3, x4, x5);
@@ -879,13 +850,6 @@ struct Invoker4;
template <typename StorageType, typename R,typename X1, typename X2,
typename X3, typename X4>
struct Invoker4<StorageType, R(*)(X1, X2, X3, X4)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ||
- is_non_const_reference<X3>::value ||
- is_non_const_reference<X4>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
static R DoInvoke(InvokerStorageBase* base) {
StorageType* invoker = static_cast<StorageType*>(base);
return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_),
@@ -897,12 +861,6 @@ struct Invoker4<StorageType, R(*)(X1, X2, X3, X4)> {
template <typename StorageType, typename R, typename T, typename X1,
typename X2, typename X3>
struct Invoker4<StorageType, R(T::*)(X1, X2, X3)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ||
- is_non_const_reference<X3>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
static R DoInvoke(InvokerStorageBase* base) {
StorageType* invoker = static_cast<StorageType*>(base);
return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_),
@@ -914,15 +872,8 @@ struct Invoker4<StorageType, R(T::*)(X1, X2, X3)> {
template <typename StorageType, typename R,typename X1, typename X2,
typename X3, typename X4, typename X5>
struct Invoker4<StorageType, R(*)(X1, X2, X3, X4, X5)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ||
- is_non_const_reference<X3>::value ||
- is_non_const_reference<X4>::value ||
- is_non_const_reference<X5>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
- static R DoInvoke(InvokerStorageBase* base, const X5& x5) {
+ static R DoInvoke(InvokerStorageBase* base,
+ typename internal::ParamTraits<X5>::ForwardType x5) {
StorageType* invoker = static_cast<StorageType*>(base);
return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_),
Unwrap(invoker->p3_), Unwrap(invoker->p4_), x5);
@@ -933,14 +884,8 @@ struct Invoker4<StorageType, R(*)(X1, X2, X3, X4, X5)> {
template <typename StorageType, typename R, typename T, typename X1,
typename X2, typename X3, typename X4>
struct Invoker4<StorageType, R(T::*)(X1, X2, X3, X4)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ||
- is_non_const_reference<X3>::value ||
- is_non_const_reference<X4>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
- static R DoInvoke(InvokerStorageBase* base, const X4& x4) {
+ static R DoInvoke(InvokerStorageBase* base,
+ typename internal::ParamTraits<X4>::ForwardType x4) {
StorageType* invoker = static_cast<StorageType*>(base);
return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_),
Unwrap(invoker->p3_), Unwrap(invoker->p4_), x4);
@@ -951,16 +896,9 @@ struct Invoker4<StorageType, R(T::*)(X1, X2, X3, X4)> {
template <typename StorageType, typename R,typename X1, typename X2,
typename X3, typename X4, typename X5, typename X6>
struct Invoker4<StorageType, R(*)(X1, X2, X3, X4, X5, X6)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ||
- is_non_const_reference<X3>::value ||
- is_non_const_reference<X4>::value ||
- is_non_const_reference<X5>::value ||
- is_non_const_reference<X6>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
- static R DoInvoke(InvokerStorageBase* base, const X5& x5, const X6& x6) {
+ static R DoInvoke(InvokerStorageBase* base,
+ typename internal::ParamTraits<X5>::ForwardType x5,
+ typename internal::ParamTraits<X6>::ForwardType x6) {
StorageType* invoker = static_cast<StorageType*>(base);
return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_),
Unwrap(invoker->p3_), Unwrap(invoker->p4_), x5, x6);
@@ -971,15 +909,9 @@ struct Invoker4<StorageType, R(*)(X1, X2, X3, X4, X5, X6)> {
template <typename StorageType, typename R, typename T, typename X1,
typename X2, typename X3, typename X4, typename X5>
struct Invoker4<StorageType, R(T::*)(X1, X2, X3, X4, X5)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ||
- is_non_const_reference<X3>::value ||
- is_non_const_reference<X4>::value ||
- is_non_const_reference<X5>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
- static R DoInvoke(InvokerStorageBase* base, const X4& x4, const X5& x5) {
+ static R DoInvoke(InvokerStorageBase* base,
+ typename internal::ParamTraits<X4>::ForwardType x4,
+ typename internal::ParamTraits<X5>::ForwardType x5) {
StorageType* invoker = static_cast<StorageType*>(base);
return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_),
Unwrap(invoker->p3_), Unwrap(invoker->p4_), x4, x5);
@@ -993,14 +925,6 @@ struct Invoker5;
template <typename StorageType, typename R,typename X1, typename X2,
typename X3, typename X4, typename X5>
struct Invoker5<StorageType, R(*)(X1, X2, X3, X4, X5)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ||
- is_non_const_reference<X3>::value ||
- is_non_const_reference<X4>::value ||
- is_non_const_reference<X5>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
static R DoInvoke(InvokerStorageBase* base) {
StorageType* invoker = static_cast<StorageType*>(base);
return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_),
@@ -1012,13 +936,6 @@ struct Invoker5<StorageType, R(*)(X1, X2, X3, X4, X5)> {
template <typename StorageType, typename R, typename T, typename X1,
typename X2, typename X3, typename X4>
struct Invoker5<StorageType, R(T::*)(X1, X2, X3, X4)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ||
- is_non_const_reference<X3>::value ||
- is_non_const_reference<X4>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
static R DoInvoke(InvokerStorageBase* base) {
StorageType* invoker = static_cast<StorageType*>(base);
return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_),
@@ -1030,16 +947,8 @@ struct Invoker5<StorageType, R(T::*)(X1, X2, X3, X4)> {
template <typename StorageType, typename R,typename X1, typename X2,
typename X3, typename X4, typename X5, typename X6>
struct Invoker5<StorageType, R(*)(X1, X2, X3, X4, X5, X6)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ||
- is_non_const_reference<X3>::value ||
- is_non_const_reference<X4>::value ||
- is_non_const_reference<X5>::value ||
- is_non_const_reference<X6>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
- static R DoInvoke(InvokerStorageBase* base, const X6& x6) {
+ static R DoInvoke(InvokerStorageBase* base,
+ typename internal::ParamTraits<X6>::ForwardType x6) {
StorageType* invoker = static_cast<StorageType*>(base);
return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_),
Unwrap(invoker->p3_), Unwrap(invoker->p4_), Unwrap(invoker->p5_), x6);
@@ -1050,15 +959,8 @@ struct Invoker5<StorageType, R(*)(X1, X2, X3, X4, X5, X6)> {
template <typename StorageType, typename R, typename T, typename X1,
typename X2, typename X3, typename X4, typename X5>
struct Invoker5<StorageType, R(T::*)(X1, X2, X3, X4, X5)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ||
- is_non_const_reference<X3>::value ||
- is_non_const_reference<X4>::value ||
- is_non_const_reference<X5>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
- static R DoInvoke(InvokerStorageBase* base, const X5& x5) {
+ static R DoInvoke(InvokerStorageBase* base,
+ typename internal::ParamTraits<X5>::ForwardType x5) {
StorageType* invoker = static_cast<StorageType*>(base);
return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_),
Unwrap(invoker->p3_), Unwrap(invoker->p4_), Unwrap(invoker->p5_), x5);
@@ -1072,15 +974,6 @@ struct Invoker6;
template <typename StorageType, typename R,typename X1, typename X2,
typename X3, typename X4, typename X5, typename X6>
struct Invoker6<StorageType, R(*)(X1, X2, X3, X4, X5, X6)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ||
- is_non_const_reference<X3>::value ||
- is_non_const_reference<X4>::value ||
- is_non_const_reference<X5>::value ||
- is_non_const_reference<X6>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
static R DoInvoke(InvokerStorageBase* base) {
StorageType* invoker = static_cast<StorageType*>(base);
return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_),
@@ -1093,14 +986,6 @@ struct Invoker6<StorageType, R(*)(X1, X2, X3, X4, X5, X6)> {
template <typename StorageType, typename R, typename T, typename X1,
typename X2, typename X3, typename X4, typename X5>
struct Invoker6<StorageType, R(T::*)(X1, X2, X3, X4, X5)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ||
- is_non_const_reference<X3>::value ||
- is_non_const_reference<X4>::value ||
- is_non_const_reference<X5>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
static R DoInvoke(InvokerStorageBase* base) {
StorageType* invoker = static_cast<StorageType*>(base);
return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_),
@@ -1133,6 +1018,7 @@ class InvokerStorage0 : public InvokerStorageBase {
typedef typename TargetTraits::IsMethod IsMethod;
+
InvokerStorage0(Sig f)
: f_(f) {
}
@@ -1149,6 +1035,7 @@ class InvokerStorage1 : public InvokerStorageBase {
typedef FunctionTraits<Sig> TargetTraits;
typedef Invoker1<StorageType, typename TargetTraits::NormalizedSig> Invoker;
typedef typename TargetTraits::IsMethod IsMethod;
+
// For methods, we need to be careful for parameter 1. We skip the
// scoped_refptr check because the binder itself takes care of this. We also
// disallow binding of an array as the method's target object.
@@ -1158,9 +1045,18 @@ class InvokerStorage1 : public InvokerStorageBase {
COMPILE_ASSERT(!IsMethod::value || !is_array<P1>::value,
first_bound_argument_to_method_cannot_be_array);
+ // Do not allow binding a non-const reference parameter. Non-const reference
+ // parameters are disallowed by the Google style guide. Also, binding a
+ // non-const reference parameter can make for subtle bugs because the
+ // invoked function will receive a reference to the stored copy of the
+ // argument and not the original.
+ COMPILE_ASSERT(
+ !( is_non_const_reference<typename TargetTraits::B1>::value ),
+ do_not_bind_functions_with_nonconst_ref);
+
InvokerStorage1(Sig f, const P1& p1)
- : f_(f), p1_(static_cast<typename BindType<P1>::StorageType>(p1)) {
+ : f_(f), p1_(static_cast<typename ParamTraits<P1>::StorageType>(p1)) {
MaybeRefcount<IsMethod, P1>::AddRef(p1_);
}
@@ -1169,7 +1065,7 @@ class InvokerStorage1 : public InvokerStorageBase {
}
Sig f_;
- typename BindType<P1>::StorageType p1_;
+ typename ParamTraits<P1>::StorageType p1_;
};
template <typename Sig, typename P1, typename P2>
@@ -1179,6 +1075,7 @@ class InvokerStorage2 : public InvokerStorageBase {
typedef FunctionTraits<Sig> TargetTraits;
typedef Invoker2<StorageType, typename TargetTraits::NormalizedSig> Invoker;
typedef typename TargetTraits::IsMethod IsMethod;
+
// For methods, we need to be careful for parameter 1. We skip the
// scoped_refptr check because the binder itself takes care of this. We also
// disallow binding of an array as the method's target object.
@@ -1190,10 +1087,20 @@ class InvokerStorage2 : public InvokerStorageBase {
COMPILE_ASSERT(!internal::UnsafeBindtoRefCountedArg<P2>::value,
p2_is_refcounted_type_and_needs_scoped_refptr);
+ // Do not allow binding a non-const reference parameter. Non-const reference
+ // parameters are disallowed by the Google style guide. Also, binding a
+ // non-const reference parameter can make for subtle bugs because the
+ // invoked function will receive a reference to the stored copy of the
+ // argument and not the original.
+ COMPILE_ASSERT(
+ !( is_non_const_reference<typename TargetTraits::B1>::value ||
+ is_non_const_reference<typename TargetTraits::B2>::value ),
+ do_not_bind_functions_with_nonconst_ref);
+
InvokerStorage2(Sig f, const P1& p1, const P2& p2)
- : f_(f), p1_(static_cast<typename BindType<P1>::StorageType>(p1)),
- p2_(static_cast<typename BindType<P2>::StorageType>(p2)) {
+ : f_(f), p1_(static_cast<typename ParamTraits<P1>::StorageType>(p1)),
+ p2_(static_cast<typename ParamTraits<P2>::StorageType>(p2)) {
MaybeRefcount<IsMethod, P1>::AddRef(p1_);
}
@@ -1202,8 +1109,8 @@ class InvokerStorage2 : public InvokerStorageBase {
}
Sig f_;
- typename BindType<P1>::StorageType p1_;
- typename BindType<P2>::StorageType p2_;
+ typename ParamTraits<P1>::StorageType p1_;
+ typename ParamTraits<P2>::StorageType p2_;
};
template <typename Sig, typename P1, typename P2, typename P3>
@@ -1213,6 +1120,7 @@ class InvokerStorage3 : public InvokerStorageBase {
typedef FunctionTraits<Sig> TargetTraits;
typedef Invoker3<StorageType, typename TargetTraits::NormalizedSig> Invoker;
typedef typename TargetTraits::IsMethod IsMethod;
+
// For methods, we need to be careful for parameter 1. We skip the
// scoped_refptr check because the binder itself takes care of this. We also
// disallow binding of an array as the method's target object.
@@ -1226,11 +1134,22 @@ class InvokerStorage3 : public InvokerStorageBase {
COMPILE_ASSERT(!internal::UnsafeBindtoRefCountedArg<P3>::value,
p3_is_refcounted_type_and_needs_scoped_refptr);
+ // Do not allow binding a non-const reference parameter. Non-const reference
+ // parameters are disallowed by the Google style guide. Also, binding a
+ // non-const reference parameter can make for subtle bugs because the
+ // invoked function will receive a reference to the stored copy of the
+ // argument and not the original.
+ COMPILE_ASSERT(
+ !( is_non_const_reference<typename TargetTraits::B1>::value ||
+ is_non_const_reference<typename TargetTraits::B2>::value ||
+ is_non_const_reference<typename TargetTraits::B3>::value ),
+ do_not_bind_functions_with_nonconst_ref);
+
InvokerStorage3(Sig f, const P1& p1, const P2& p2, const P3& p3)
- : f_(f), p1_(static_cast<typename BindType<P1>::StorageType>(p1)),
- p2_(static_cast<typename BindType<P2>::StorageType>(p2)),
- p3_(static_cast<typename BindType<P3>::StorageType>(p3)) {
+ : f_(f), p1_(static_cast<typename ParamTraits<P1>::StorageType>(p1)),
+ p2_(static_cast<typename ParamTraits<P2>::StorageType>(p2)),
+ p3_(static_cast<typename ParamTraits<P3>::StorageType>(p3)) {
MaybeRefcount<IsMethod, P1>::AddRef(p1_);
}
@@ -1239,9 +1158,9 @@ class InvokerStorage3 : public InvokerStorageBase {
}
Sig f_;
- typename BindType<P1>::StorageType p1_;
- typename BindType<P2>::StorageType p2_;
- typename BindType<P3>::StorageType p3_;
+ typename ParamTraits<P1>::StorageType p1_;
+ typename ParamTraits<P2>::StorageType p2_;
+ typename ParamTraits<P3>::StorageType p3_;
};
template <typename Sig, typename P1, typename P2, typename P3, typename P4>
@@ -1251,6 +1170,7 @@ class InvokerStorage4 : public InvokerStorageBase {
typedef FunctionTraits<Sig> TargetTraits;
typedef Invoker4<StorageType, typename TargetTraits::NormalizedSig> Invoker;
typedef typename TargetTraits::IsMethod IsMethod;
+
// For methods, we need to be careful for parameter 1. We skip the
// scoped_refptr check because the binder itself takes care of this. We also
// disallow binding of an array as the method's target object.
@@ -1266,12 +1186,24 @@ class InvokerStorage4 : public InvokerStorageBase {
COMPILE_ASSERT(!internal::UnsafeBindtoRefCountedArg<P4>::value,
p4_is_refcounted_type_and_needs_scoped_refptr);
+ // Do not allow binding a non-const reference parameter. Non-const reference
+ // parameters are disallowed by the Google style guide. Also, binding a
+ // non-const reference parameter can make for subtle bugs because the
+ // invoked function will receive a reference to the stored copy of the
+ // argument and not the original.
+ COMPILE_ASSERT(
+ !( is_non_const_reference<typename TargetTraits::B1>::value ||
+ is_non_const_reference<typename TargetTraits::B2>::value ||
+ is_non_const_reference<typename TargetTraits::B3>::value ||
+ is_non_const_reference<typename TargetTraits::B4>::value ),
+ do_not_bind_functions_with_nonconst_ref);
+
InvokerStorage4(Sig f, const P1& p1, const P2& p2, const P3& p3, const P4& p4)
- : f_(f), p1_(static_cast<typename BindType<P1>::StorageType>(p1)),
- p2_(static_cast<typename BindType<P2>::StorageType>(p2)),
- p3_(static_cast<typename BindType<P3>::StorageType>(p3)),
- p4_(static_cast<typename BindType<P4>::StorageType>(p4)) {
+ : f_(f), p1_(static_cast<typename ParamTraits<P1>::StorageType>(p1)),
+ p2_(static_cast<typename ParamTraits<P2>::StorageType>(p2)),
+ p3_(static_cast<typename ParamTraits<P3>::StorageType>(p3)),
+ p4_(static_cast<typename ParamTraits<P4>::StorageType>(p4)) {
MaybeRefcount<IsMethod, P1>::AddRef(p1_);
}
@@ -1280,10 +1212,10 @@ class InvokerStorage4 : public InvokerStorageBase {
}
Sig f_;
- typename BindType<P1>::StorageType p1_;
- typename BindType<P2>::StorageType p2_;
- typename BindType<P3>::StorageType p3_;
- typename BindType<P4>::StorageType p4_;
+ typename ParamTraits<P1>::StorageType p1_;
+ typename ParamTraits<P2>::StorageType p2_;
+ typename ParamTraits<P3>::StorageType p3_;
+ typename ParamTraits<P4>::StorageType p4_;
};
template <typename Sig, typename P1, typename P2, typename P3, typename P4,
@@ -1294,6 +1226,7 @@ class InvokerStorage5 : public InvokerStorageBase {
typedef FunctionTraits<Sig> TargetTraits;
typedef Invoker5<StorageType, typename TargetTraits::NormalizedSig> Invoker;
typedef typename TargetTraits::IsMethod IsMethod;
+
// For methods, we need to be careful for parameter 1. We skip the
// scoped_refptr check because the binder itself takes care of this. We also
// disallow binding of an array as the method's target object.
@@ -1311,14 +1244,27 @@ class InvokerStorage5 : public InvokerStorageBase {
COMPILE_ASSERT(!internal::UnsafeBindtoRefCountedArg<P5>::value,
p5_is_refcounted_type_and_needs_scoped_refptr);
+ // Do not allow binding a non-const reference parameter. Non-const reference
+ // parameters are disallowed by the Google style guide. Also, binding a
+ // non-const reference parameter can make for subtle bugs because the
+ // invoked function will receive a reference to the stored copy of the
+ // argument and not the original.
+ COMPILE_ASSERT(
+ !( is_non_const_reference<typename TargetTraits::B1>::value ||
+ is_non_const_reference<typename TargetTraits::B2>::value ||
+ is_non_const_reference<typename TargetTraits::B3>::value ||
+ is_non_const_reference<typename TargetTraits::B4>::value ||
+ is_non_const_reference<typename TargetTraits::B5>::value ),
+ do_not_bind_functions_with_nonconst_ref);
+
InvokerStorage5(Sig f, const P1& p1, const P2& p2, const P3& p3,
const P4& p4, const P5& p5)
- : f_(f), p1_(static_cast<typename BindType<P1>::StorageType>(p1)),
- p2_(static_cast<typename BindType<P2>::StorageType>(p2)),
- p3_(static_cast<typename BindType<P3>::StorageType>(p3)),
- p4_(static_cast<typename BindType<P4>::StorageType>(p4)),
- p5_(static_cast<typename BindType<P5>::StorageType>(p5)) {
+ : f_(f), p1_(static_cast<typename ParamTraits<P1>::StorageType>(p1)),
+ p2_(static_cast<typename ParamTraits<P2>::StorageType>(p2)),
+ p3_(static_cast<typename ParamTraits<P3>::StorageType>(p3)),
+ p4_(static_cast<typename ParamTraits<P4>::StorageType>(p4)),
+ p5_(static_cast<typename ParamTraits<P5>::StorageType>(p5)) {
MaybeRefcount<IsMethod, P1>::AddRef(p1_);
}
@@ -1327,11 +1273,11 @@ class InvokerStorage5 : public InvokerStorageBase {
}
Sig f_;
- typename BindType<P1>::StorageType p1_;
- typename BindType<P2>::StorageType p2_;
- typename BindType<P3>::StorageType p3_;
- typename BindType<P4>::StorageType p4_;
- typename BindType<P5>::StorageType p5_;
+ typename ParamTraits<P1>::StorageType p1_;
+ typename ParamTraits<P2>::StorageType p2_;
+ typename ParamTraits<P3>::StorageType p3_;
+ typename ParamTraits<P4>::StorageType p4_;
+ typename ParamTraits<P5>::StorageType p5_;
};
template <typename Sig, typename P1, typename P2, typename P3, typename P4,
@@ -1342,6 +1288,7 @@ class InvokerStorage6 : public InvokerStorageBase {
typedef FunctionTraits<Sig> TargetTraits;
typedef Invoker6<StorageType, typename TargetTraits::NormalizedSig> Invoker;
typedef typename TargetTraits::IsMethod IsMethod;
+
// For methods, we need to be careful for parameter 1. We skip the
// scoped_refptr check because the binder itself takes care of this. We also
// disallow binding of an array as the method's target object.
@@ -1361,15 +1308,29 @@ class InvokerStorage6 : public InvokerStorageBase {
COMPILE_ASSERT(!internal::UnsafeBindtoRefCountedArg<P6>::value,
p6_is_refcounted_type_and_needs_scoped_refptr);
+ // Do not allow binding a non-const reference parameter. Non-const reference
+ // parameters are disallowed by the Google style guide. Also, binding a
+ // non-const reference parameter can make for subtle bugs because the
+ // invoked function will receive a reference to the stored copy of the
+ // argument and not the original.
+ COMPILE_ASSERT(
+ !( is_non_const_reference<typename TargetTraits::B1>::value ||
+ is_non_const_reference<typename TargetTraits::B2>::value ||
+ is_non_const_reference<typename TargetTraits::B3>::value ||
+ is_non_const_reference<typename TargetTraits::B4>::value ||
+ is_non_const_reference<typename TargetTraits::B5>::value ||
+ is_non_const_reference<typename TargetTraits::B6>::value ),
+ do_not_bind_functions_with_nonconst_ref);
+
InvokerStorage6(Sig f, const P1& p1, const P2& p2, const P3& p3,
const P4& p4, const P5& p5, const P6& p6)
- : f_(f), p1_(static_cast<typename BindType<P1>::StorageType>(p1)),
- p2_(static_cast<typename BindType<P2>::StorageType>(p2)),
- p3_(static_cast<typename BindType<P3>::StorageType>(p3)),
- p4_(static_cast<typename BindType<P4>::StorageType>(p4)),
- p5_(static_cast<typename BindType<P5>::StorageType>(p5)),
- p6_(static_cast<typename BindType<P6>::StorageType>(p6)) {
+ : f_(f), p1_(static_cast<typename ParamTraits<P1>::StorageType>(p1)),
+ p2_(static_cast<typename ParamTraits<P2>::StorageType>(p2)),
+ p3_(static_cast<typename ParamTraits<P3>::StorageType>(p3)),
+ p4_(static_cast<typename ParamTraits<P4>::StorageType>(p4)),
+ p5_(static_cast<typename ParamTraits<P5>::StorageType>(p5)),
+ p6_(static_cast<typename ParamTraits<P6>::StorageType>(p6)) {
MaybeRefcount<IsMethod, P1>::AddRef(p1_);
}
@@ -1378,12 +1339,12 @@ class InvokerStorage6 : public InvokerStorageBase {
}
Sig f_;
- typename BindType<P1>::StorageType p1_;
- typename BindType<P2>::StorageType p2_;
- typename BindType<P3>::StorageType p3_;
- typename BindType<P4>::StorageType p4_;
- typename BindType<P5>::StorageType p5_;
- typename BindType<P6>::StorageType p6_;
+ typename ParamTraits<P1>::StorageType p1_;
+ typename ParamTraits<P2>::StorageType p2_;
+ typename ParamTraits<P3>::StorageType p3_;
+ typename ParamTraits<P4>::StorageType p4_;
+ typename ParamTraits<P5>::StorageType p5_;
+ typename ParamTraits<P6>::StorageType p6_;
};
} // namespace internal
diff --git a/base/bind_internal.h.pump b/base/bind_internal.h.pump
index 84fb2ef..4ccec5e 100644
--- a/base/bind_internal.h.pump
+++ b/base/bind_internal.h.pump
@@ -82,6 +82,17 @@ $if ARITY > 0[[, ]] $for ARG , [[typename X$(ARG)]]>
struct FunctionTraits<R(*)($for ARG , [[X$(ARG)]])> {
typedef R (*NormalizedSig)($for ARG , [[X$(ARG)]]);
typedef false_type IsMethod;
+
+$if ARITY > 0 [[
+
+ // Target type for each bound parameter.
+
+$for ARG [[
+ typedef X$(ARG) B$(ARG);
+
+]] $$ for ARG
+]] $$ if ARITY > 0
+
};
// Method: Arity $(ARITY).
@@ -90,6 +101,15 @@ $if ARITY > 0[[, ]] $for ARG , [[typename X$(ARG)]]>
struct FunctionTraits<R(T::*)($for ARG , [[X$(ARG)]])> {
typedef R (T::*NormalizedSig)($for ARG , [[X$(ARG)]]);
typedef true_type IsMethod;
+
+ // Target type for each bound parameter.
+ typedef T B1;
+
+$for ARG [[
+ typedef X$(ARG) B$(ARG + 1);
+
+]] $$ for ARG
+
};
// Const Method: Arity $(ARITY).
@@ -98,6 +118,15 @@ $if ARITY > 0[[, ]] $for ARG , [[typename X$(ARG)]]>
struct FunctionTraits<R(T::*)($for ARG , [[X$(ARG)]]) const> {
typedef R (T::*NormalizedSig)($for ARG , [[X$(ARG)]]);
typedef true_type IsMethod;
+
+ // Target type for each bound parameter.
+ typedef T B1;
+
+$for ARG [[
+ typedef X$(ARG) B$(ARG + 1);
+
+]] $$ for ARG
+
};
]] $$for ARITY
@@ -151,17 +180,9 @@ template <typename StorageType, typename R[[]]
$if ARITY > 0 [[,]][[]]
$for ARG , [[typename X$(ARG)]]>
struct Invoker$(BOUND)<StorageType, R(*)($for ARG , [[X$(ARG)]])> {
-$if ARITY > 0 [[
-
- COMPILE_ASSERT(
- !($for ARG || [[ is_non_const_reference<X$(ARG)>::value ]]),
- do_not_bind_functions_with_nonconst_ref);
-
-]]
-
static R DoInvoke(InvokerStorageBase* base[[]]
$if UNBOUND != 0 [[, ]][[]]
-$for UNBOUND_ARG , [[const X$(UNBOUND_ARG)& x$(UNBOUND_ARG)]]) {
+$for UNBOUND_ARG , [[typename internal::ParamTraits<X$(UNBOUND_ARG)>::ForwardType x$(UNBOUND_ARG)]]) {
StorageType* invoker = static_cast<StorageType*>(base);
return invoker->f_($for BOUND_ARG , [[Unwrap(invoker->p$(BOUND_ARG)_)]][[]]
$$ Add comma if there are both boudn and unbound args.
@@ -176,17 +197,9 @@ $if BOUND > 0 [[
template <typename StorageType, typename R, typename T[[]]
$if M_ARITY > 0[[, ]] $for M_ARG , [[typename X$(M_ARG)]]>
struct Invoker$(BOUND)<StorageType, R(T::*)($for M_ARG , [[X$(M_ARG)]])> {
-$if M_ARITY > 0 [[
-
- COMPILE_ASSERT(
- !($for M_ARG || [[ is_non_const_reference<X$(M_ARG)>::value ]]),
- do_not_bind_functions_with_nonconst_ref);
-
-]]
-
static R DoInvoke(InvokerStorageBase* base[[]]
$if UNBOUND > 0 [[, ]][[]]
-$for M_UNBOUND_ARG , [[const X$(M_UNBOUND_ARG)& x$(M_UNBOUND_ARG)]]) {
+$for M_UNBOUND_ARG , [[typename internal::ParamTraits<X$(M_UNBOUND_ARG)>::ForwardType x$(M_UNBOUND_ARG)]]) {
StorageType* invoker = static_cast<StorageType*>(base);
return (Unwrap(invoker->p1_)->*invoker->f_)([[]]
$for M_BOUND_ARG , [[Unwrap(invoker->p$(M_BOUND_ARG)_)]][[]]
@@ -228,6 +241,7 @@ class InvokerStorage$(BOUND) : public InvokerStorageBase {
typedef FunctionTraits<Sig> TargetTraits;
typedef Invoker$(BOUND)<StorageType, typename TargetTraits::NormalizedSig> Invoker;
typedef typename TargetTraits::IsMethod IsMethod;
+
$for BOUND_ARG [[
$if BOUND_ARG == 1 [[
@@ -247,6 +261,19 @@ $if BOUND_ARG == 1 [[
]] $$ $for BOUND_ARG
+$if BOUND > 0 [[
+
+ // Do not allow binding a non-const reference parameter. Non-const reference
+ // parameters are disallowed by the Google style guide. Also, binding a
+ // non-const reference parameter can make for subtle bugs because the
+ // invoked function will receive a reference to the stored copy of the
+ // argument and not the original.
+ COMPILE_ASSERT(
+ !($for BOUND_ARG || [[ is_non_const_reference<typename TargetTraits::B$(BOUND_ARG)>::value ]]),
+ do_not_bind_functions_with_nonconst_ref);
+
+]]
+
InvokerStorage$(BOUND)(Sig f
$if BOUND > 0 [[, ]]
@@ -256,7 +283,7 @@ $if BOUND == 0 [[
{
]] $else [[
-, $for BOUND_ARG , [[p$(BOUND_ARG)_(static_cast<typename BindType<P$(BOUND_ARG)>::StorageType>(p$(BOUND_ARG)))]] {
+, $for BOUND_ARG , [[p$(BOUND_ARG)_(static_cast<typename ParamTraits<P$(BOUND_ARG)>::StorageType>(p$(BOUND_ARG)))]] {
MaybeRefcount<IsMethod, P1>::AddRef(p1_);
]]
@@ -273,7 +300,7 @@ $if BOUND > 0 [[
Sig f_;
$for BOUND_ARG [[
- typename BindType<P$(BOUND_ARG)>::StorageType p$(BOUND_ARG)_;
+ typename ParamTraits<P$(BOUND_ARG)>::StorageType p$(BOUND_ARG)_;
]]
};
diff --git a/base/bind_internal_win.h b/base/bind_internal_win.h
index dab8d51..976a4d7 100644
--- a/base/bind_internal_win.h
+++ b/base/bind_internal_win.h
@@ -3,6 +3,7 @@
// DO NOT EDIT BY HAND!!!
+
// Copyright (c) 2011 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.
@@ -39,6 +40,8 @@ template <typename R, typename X1>
struct FunctionTraits<R(__stdcall *)(X1)> {
typedef R (*NormalizedSig)(X1);
typedef false_type IsMethod;
+ // Target type for each bound parameter.
+ typedef X1 B1;
};
// __fastcall Function: Arity 1.
@@ -46,6 +49,8 @@ template <typename R, typename X1>
struct FunctionTraits<R(__fastcall *)(X1)> {
typedef R (*NormalizedSig)(X1);
typedef false_type IsMethod;
+ // Target type for each bound parameter.
+ typedef X1 B1;
};
// __stdcall Function: Arity 2.
@@ -53,6 +58,9 @@ template <typename R, typename X1, typename X2>
struct FunctionTraits<R(__stdcall *)(X1, X2)> {
typedef R (*NormalizedSig)(X1, X2);
typedef false_type IsMethod;
+ // Target type for each bound parameter.
+ typedef X1 B1;
+ typedef X2 B2;
};
// __fastcall Function: Arity 2.
@@ -60,6 +68,9 @@ template <typename R, typename X1, typename X2>
struct FunctionTraits<R(__fastcall *)(X1, X2)> {
typedef R (*NormalizedSig)(X1, X2);
typedef false_type IsMethod;
+ // Target type for each bound parameter.
+ typedef X1 B1;
+ typedef X2 B2;
};
// __stdcall Function: Arity 3.
@@ -67,6 +78,10 @@ template <typename R, typename X1, typename X2, typename X3>
struct FunctionTraits<R(__stdcall *)(X1, X2, X3)> {
typedef R (*NormalizedSig)(X1, X2, X3);
typedef false_type IsMethod;
+ // Target type for each bound parameter.
+ typedef X1 B1;
+ typedef X2 B2;
+ typedef X3 B3;
};
// __fastcall Function: Arity 3.
@@ -74,6 +89,10 @@ template <typename R, typename X1, typename X2, typename X3>
struct FunctionTraits<R(__fastcall *)(X1, X2, X3)> {
typedef R (*NormalizedSig)(X1, X2, X3);
typedef false_type IsMethod;
+ // Target type for each bound parameter.
+ typedef X1 B1;
+ typedef X2 B2;
+ typedef X3 B3;
};
// __stdcall Function: Arity 4.
@@ -81,6 +100,11 @@ template <typename R, typename X1, typename X2, typename X3, typename X4>
struct FunctionTraits<R(__stdcall *)(X1, X2, X3, X4)> {
typedef R (*NormalizedSig)(X1, X2, X3, X4);
typedef false_type IsMethod;
+ // Target type for each bound parameter.
+ typedef X1 B1;
+ typedef X2 B2;
+ typedef X3 B3;
+ typedef X4 B4;
};
// __fastcall Function: Arity 4.
@@ -88,6 +112,11 @@ template <typename R, typename X1, typename X2, typename X3, typename X4>
struct FunctionTraits<R(__fastcall *)(X1, X2, X3, X4)> {
typedef R (*NormalizedSig)(X1, X2, X3, X4);
typedef false_type IsMethod;
+ // Target type for each bound parameter.
+ typedef X1 B1;
+ typedef X2 B2;
+ typedef X3 B3;
+ typedef X4 B4;
};
// __stdcall Function: Arity 5.
@@ -96,6 +125,12 @@ template <typename R, typename X1, typename X2, typename X3, typename X4,
struct FunctionTraits<R(__stdcall *)(X1, X2, X3, X4, X5)> {
typedef R (*NormalizedSig)(X1, X2, X3, X4, X5);
typedef false_type IsMethod;
+ // Target type for each bound parameter.
+ typedef X1 B1;
+ typedef X2 B2;
+ typedef X3 B3;
+ typedef X4 B4;
+ typedef X5 B5;
};
// __fastcall Function: Arity 5.
@@ -104,6 +139,12 @@ template <typename R, typename X1, typename X2, typename X3, typename X4,
struct FunctionTraits<R(__fastcall *)(X1, X2, X3, X4, X5)> {
typedef R (*NormalizedSig)(X1, X2, X3, X4, X5);
typedef false_type IsMethod;
+ // Target type for each bound parameter.
+ typedef X1 B1;
+ typedef X2 B2;
+ typedef X3 B3;
+ typedef X4 B4;
+ typedef X5 B5;
};
// __stdcall Function: Arity 6.
@@ -112,6 +153,13 @@ template <typename R, typename X1, typename X2, typename X3, typename X4,
struct FunctionTraits<R(__stdcall *)(X1, X2, X3, X4, X5, X6)> {
typedef R (*NormalizedSig)(X1, X2, X3, X4, X5, X6);
typedef false_type IsMethod;
+ // Target type for each bound parameter.
+ typedef X1 B1;
+ typedef X2 B2;
+ typedef X3 B3;
+ typedef X4 B4;
+ typedef X5 B5;
+ typedef X6 B6;
};
// __fastcall Function: Arity 6.
@@ -120,6 +168,13 @@ template <typename R, typename X1, typename X2, typename X3, typename X4,
struct FunctionTraits<R(__fastcall *)(X1, X2, X3, X4, X5, X6)> {
typedef R (*NormalizedSig)(X1, X2, X3, X4, X5, X6);
typedef false_type IsMethod;
+ // Target type for each bound parameter.
+ typedef X1 B1;
+ typedef X2 B2;
+ typedef X3 B3;
+ typedef X4 B4;
+ typedef X5 B5;
+ typedef X6 B6;
};
} // namespace internal
diff --git a/base/bind_internal_win.h.pump b/base/bind_internal_win.h.pump
index 4d213a3..06ceaca 100644
--- a/base/bind_internal_win.h.pump
+++ b/base/bind_internal_win.h.pump
@@ -34,6 +34,16 @@ $if ARITY > 0[[, ]] $for ARG , [[typename X$(ARG)]]>
struct FunctionTraits<R(__stdcall *)($for ARG , [[X$(ARG)]])> {
typedef R (*NormalizedSig)($for ARG , [[X$(ARG)]]);
typedef false_type IsMethod;
+
+$if ARITY > 0 [[
+
+ // Target type for each bound parameter.
+
+$for ARG [[
+ typedef X$(ARG) B$(ARG);
+
+]] $$ for ARG
+]] $$ if ARITY > 0
};
// __fastcall Function: Arity $(ARITY).
@@ -42,6 +52,16 @@ $if ARITY > 0[[, ]] $for ARG , [[typename X$(ARG)]]>
struct FunctionTraits<R(__fastcall *)($for ARG , [[X$(ARG)]])> {
typedef R (*NormalizedSig)($for ARG , [[X$(ARG)]]);
typedef false_type IsMethod;
+
+$if ARITY > 0 [[
+
+ // Target type for each bound parameter.
+
+$for ARG [[
+ typedef X$(ARG) B$(ARG);
+
+]] $$ for ARG
+]] $$ if ARITY > 0
};
]] $$for ARITY
diff --git a/base/bind_unittest.cc b/base/bind_unittest.cc
index 061808b..c131a86 100644
--- a/base/bind_unittest.cc
+++ b/base/bind_unittest.cc
@@ -48,6 +48,11 @@ class HasRef : public NoRef {
DISALLOW_COPY_AND_ASSIGN(HasRef);
};
+class HasRefPrivateDtor : public HasRef {
+ private:
+ ~HasRefPrivateDtor() {}
+};
+
static const int kParentValue = 1;
static const int kChildValue = 2;
@@ -174,6 +179,10 @@ int UnwrapNoRefParentConstRef(const NoRefParent& p) {
return p.value;
}
+void RefArgSet(int &n) {
+ n = 2;
+}
+
// Only useful in no-compile tests.
int UnwrapNoRefParentRef(Parent& p) {
return p.value;
@@ -351,6 +360,37 @@ TEST_F(BindTest, ArgumentBinding) {
EXPECT_EQ(8, bind_const_reference_promotes_cb.Run());
}
+// Unbound argument type support tests.
+// - Unbound value.
+// - Unbound pointer.
+// - Unbound reference.
+// - Unbound const reference.
+// - Unbound unsized array.
+// - Unbound sized array.
+// - Unbound array-of-arrays.
+TEST_F(BindTest, UnboundArgumentTypeSupport) {
+ Callback<void(int)> unbound_value_cb = Bind(&VoidPolymorphic1<int>);
+ Callback<void(int*)> unbound_pointer_cb = Bind(&VoidPolymorphic1<int*>);
+ Callback<void(int&)> unbound_ref_cb = Bind(&VoidPolymorphic1<int&>);
+ Callback<void(const int&)> unbound_const_ref_cb =
+ Bind(&VoidPolymorphic1<const int&>);
+ Callback<void(int[])> unbound_unsized_array_cb =
+ Bind(&VoidPolymorphic1<int[]>);
+ Callback<void(int[2])> unbound_sized_array_cb =
+ Bind(&VoidPolymorphic1<int[2]>);
+ Callback<void(int[][2])> unbound_array_of_arrays_cb =
+ Bind(&VoidPolymorphic1<int[][2]>);
+}
+
+// Function with unbound reference parameter.
+// - Original paraemter is modified by callback.
+TEST_F(BindTest, UnboundReferenceSupport) {
+ int n = 0;
+ Callback<void(int&)> unbound_ref_cb = Bind(&RefArgSet);
+ unbound_ref_cb.Run(n);
+ EXPECT_EQ(2, n);
+}
+
// Functions that take reference parameters.
// - Forced reference parameter type still stores a copy.
// - Forced const reference parameter type still stores a copy.
@@ -390,6 +430,11 @@ TEST_F(BindTest, ArrayArgumentBinding) {
// Verify SupportsAddRefAndRelease correctly introspects the class type for
// AddRef() and Release().
+// - Class with AddRef() and Release()
+// - Class without AddRef() and Release()
+// - Derived Class with AddRef() and Release()
+// - Derived Class without AddRef() and Release()
+// - Derived Class with AddRef() and Release() and a private destructor.
TEST_F(BindTest, SupportsAddRefAndRelease) {
EXPECT_TRUE(internal::SupportsAddRefAndRelease<HasRef>::value);
EXPECT_FALSE(internal::SupportsAddRefAndRelease<NoRef>::value);
@@ -399,6 +444,10 @@ TEST_F(BindTest, SupportsAddRefAndRelease) {
// inheritance.
EXPECT_TRUE(internal::SupportsAddRefAndRelease<StrictMock<HasRef> >::value);
EXPECT_FALSE(internal::SupportsAddRefAndRelease<StrictMock<NoRef> >::value);
+
+ // This matters because the implementation creates a dummy class that
+ // inherits from the template type.
+ EXPECT_TRUE(internal::SupportsAddRefAndRelease<HasRefPrivateDtor>::value);
}
// Unretained() wrapper support.
@@ -570,14 +619,13 @@ TEST_F(BindTest, NoCompile) {
//
// HasRef p[10];
// Callback<void(void)> method_bound_to_array_cb =
- // Bind(&HasRef::VoidConstMethod0, p);
+ // Bind(&HasRef::VoidConstMethod0, p);
// method_bound_to_array_cb.Run();
// - Refcounted types should not be bound as a raw pointer.
// HasRef for_raw_ptr;
// Callback<void(void)> ref_count_as_raw_ptr =
// Bind(&VoidPolymorphic1<HasRef*>, &for_raw_ptr);
- // ASSERT_EQ(&for_raw_ptr, ref_count_as_raw_ptr.Run());
}
diff --git a/base/bzip2_error_handler.cc b/base/bzip2_error_handler.cc
index 564cabd..e66bcf3 100644
--- a/base/bzip2_error_handler.cc
+++ b/base/bzip2_error_handler.cc
@@ -1,7 +1,9 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
+#include <ostream>
+
#include "base/logging.h"
// We define BZ_NO_STDIO in third_party/bzip2 to remove its internal STDERR
diff --git a/base/callback.h b/base/callback.h
index bcc3dfd..dafbc0c 100644
--- a/base/callback.h
+++ b/base/callback.h
@@ -3,6 +3,7 @@
// DO NOT EDIT BY HAND!!!
+
// Copyright (c) 2011 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.
@@ -44,8 +45,8 @@
//
// /* Binding a normal function. */
// int Return5() { return 5; }
-// base::Callback<int(int)> func_cb = base::Bind(&Return5);
-// LOG(INFO) << func_cb.Run(5); // Prints 5.
+// base::Callback<int(void)> func_cb = base::Bind(&Return5);
+// LOG(INFO) << func_cb.Run(); // Prints 5.
//
// void PrintHi() { LOG(INFO) << "hi."; }
// base::Closure void_func_cb = base::Bind(&PrintHi);
@@ -188,7 +189,7 @@
//
// These are not features that are required in Chromium. Some of them, such as
// allowing for reference parameters, and subtyping of functions, may actually
-// because a source of errors. Removing support for these features actually
+// become a source of errors. Removing support for these features actually
// allows for a simpler implementation, and a terser Currying API.
//
//
@@ -225,7 +226,8 @@ class Callback;
template <typename R>
class Callback<R(void)> : public internal::CallbackBase {
public:
- typedef R(*PolymorphicInvoke)(internal::InvokerStorageBase*);
+ typedef R(*PolymorphicInvoke)(
+ internal::InvokerStorageBase*);
Callback() : CallbackBase(NULL, NULL) { }
@@ -254,7 +256,9 @@ class Callback<R(void)> : public internal::CallbackBase {
template <typename R, typename A1>
class Callback<R(A1)> : public internal::CallbackBase {
public:
- typedef R(*PolymorphicInvoke)(internal::InvokerStorageBase*, const A1&);
+ typedef R(*PolymorphicInvoke)(
+ internal::InvokerStorageBase*,
+ typename internal::ParamTraits<A1>::ForwardType);
Callback() : CallbackBase(NULL, NULL) { }
@@ -272,7 +276,7 @@ class Callback<R(A1)> : public internal::CallbackBase {
&invoker_holder.invoker_storage_) {
}
- R Run(const A1& a1) const {
+ R Run(typename internal::ParamTraits<A1>::ForwardType a1) const {
PolymorphicInvoke f =
reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_);
@@ -283,8 +287,10 @@ class Callback<R(A1)> : public internal::CallbackBase {
template <typename R, typename A1, typename A2>
class Callback<R(A1, A2)> : public internal::CallbackBase {
public:
- typedef R(*PolymorphicInvoke)(internal::InvokerStorageBase*, const A1&,
- const A2&);
+ typedef R(*PolymorphicInvoke)(
+ internal::InvokerStorageBase*,
+ typename internal::ParamTraits<A1>::ForwardType,
+ typename internal::ParamTraits<A2>::ForwardType);
Callback() : CallbackBase(NULL, NULL) { }
@@ -302,8 +308,8 @@ class Callback<R(A1, A2)> : public internal::CallbackBase {
&invoker_holder.invoker_storage_) {
}
- R Run(const A1& a1,
- const A2& a2) const {
+ R Run(typename internal::ParamTraits<A1>::ForwardType a1,
+ typename internal::ParamTraits<A2>::ForwardType a2) const {
PolymorphicInvoke f =
reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_);
@@ -315,9 +321,11 @@ class Callback<R(A1, A2)> : public internal::CallbackBase {
template <typename R, typename A1, typename A2, typename A3>
class Callback<R(A1, A2, A3)> : public internal::CallbackBase {
public:
- typedef R(*PolymorphicInvoke)(internal::InvokerStorageBase*, const A1&,
- const A2&,
- const A3&);
+ typedef R(*PolymorphicInvoke)(
+ internal::InvokerStorageBase*,
+ typename internal::ParamTraits<A1>::ForwardType,
+ typename internal::ParamTraits<A2>::ForwardType,
+ typename internal::ParamTraits<A3>::ForwardType);
Callback() : CallbackBase(NULL, NULL) { }
@@ -335,9 +343,9 @@ class Callback<R(A1, A2, A3)> : public internal::CallbackBase {
&invoker_holder.invoker_storage_) {
}
- R Run(const A1& a1,
- const A2& a2,
- const A3& a3) const {
+ R Run(typename internal::ParamTraits<A1>::ForwardType a1,
+ typename internal::ParamTraits<A2>::ForwardType a2,
+ typename internal::ParamTraits<A3>::ForwardType a3) const {
PolymorphicInvoke f =
reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_);
@@ -350,10 +358,12 @@ class Callback<R(A1, A2, A3)> : public internal::CallbackBase {
template <typename R, typename A1, typename A2, typename A3, typename A4>
class Callback<R(A1, A2, A3, A4)> : public internal::CallbackBase {
public:
- typedef R(*PolymorphicInvoke)(internal::InvokerStorageBase*, const A1&,
- const A2&,
- const A3&,
- const A4&);
+ typedef R(*PolymorphicInvoke)(
+ internal::InvokerStorageBase*,
+ typename internal::ParamTraits<A1>::ForwardType,
+ typename internal::ParamTraits<A2>::ForwardType,
+ typename internal::ParamTraits<A3>::ForwardType,
+ typename internal::ParamTraits<A4>::ForwardType);
Callback() : CallbackBase(NULL, NULL) { }
@@ -371,10 +381,10 @@ class Callback<R(A1, A2, A3, A4)> : public internal::CallbackBase {
&invoker_holder.invoker_storage_) {
}
- R Run(const A1& a1,
- const A2& a2,
- const A3& a3,
- const A4& a4) const {
+ R Run(typename internal::ParamTraits<A1>::ForwardType a1,
+ typename internal::ParamTraits<A2>::ForwardType a2,
+ typename internal::ParamTraits<A3>::ForwardType a3,
+ typename internal::ParamTraits<A4>::ForwardType a4) const {
PolymorphicInvoke f =
reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_);
@@ -389,11 +399,13 @@ template <typename R, typename A1, typename A2, typename A3, typename A4,
typename A5>
class Callback<R(A1, A2, A3, A4, A5)> : public internal::CallbackBase {
public:
- typedef R(*PolymorphicInvoke)(internal::InvokerStorageBase*, const A1&,
- const A2&,
- const A3&,
- const A4&,
- const A5&);
+ typedef R(*PolymorphicInvoke)(
+ internal::InvokerStorageBase*,
+ typename internal::ParamTraits<A1>::ForwardType,
+ typename internal::ParamTraits<A2>::ForwardType,
+ typename internal::ParamTraits<A3>::ForwardType,
+ typename internal::ParamTraits<A4>::ForwardType,
+ typename internal::ParamTraits<A5>::ForwardType);
Callback() : CallbackBase(NULL, NULL) { }
@@ -411,11 +423,11 @@ class Callback<R(A1, A2, A3, A4, A5)> : public internal::CallbackBase {
&invoker_holder.invoker_storage_) {
}
- R Run(const A1& a1,
- const A2& a2,
- const A3& a3,
- const A4& a4,
- const A5& a5) const {
+ R Run(typename internal::ParamTraits<A1>::ForwardType a1,
+ typename internal::ParamTraits<A2>::ForwardType a2,
+ typename internal::ParamTraits<A3>::ForwardType a3,
+ typename internal::ParamTraits<A4>::ForwardType a4,
+ typename internal::ParamTraits<A5>::ForwardType a5) const {
PolymorphicInvoke f =
reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_);
@@ -431,12 +443,14 @@ template <typename R, typename A1, typename A2, typename A3, typename A4,
typename A5, typename A6>
class Callback<R(A1, A2, A3, A4, A5, A6)> : public internal::CallbackBase {
public:
- typedef R(*PolymorphicInvoke)(internal::InvokerStorageBase*, const A1&,
- const A2&,
- const A3&,
- const A4&,
- const A5&,
- const A6&);
+ typedef R(*PolymorphicInvoke)(
+ internal::InvokerStorageBase*,
+ typename internal::ParamTraits<A1>::ForwardType,
+ typename internal::ParamTraits<A2>::ForwardType,
+ typename internal::ParamTraits<A3>::ForwardType,
+ typename internal::ParamTraits<A4>::ForwardType,
+ typename internal::ParamTraits<A5>::ForwardType,
+ typename internal::ParamTraits<A6>::ForwardType);
Callback() : CallbackBase(NULL, NULL) { }
@@ -454,12 +468,12 @@ class Callback<R(A1, A2, A3, A4, A5, A6)> : public internal::CallbackBase {
&invoker_holder.invoker_storage_) {
}
- R Run(const A1& a1,
- const A2& a2,
- const A3& a3,
- const A4& a4,
- const A5& a5,
- const A6& a6) const {
+ R Run(typename internal::ParamTraits<A1>::ForwardType a1,
+ typename internal::ParamTraits<A2>::ForwardType a2,
+ typename internal::ParamTraits<A3>::ForwardType a3,
+ typename internal::ParamTraits<A4>::ForwardType a4,
+ typename internal::ParamTraits<A5>::ForwardType a5,
+ typename internal::ParamTraits<A6>::ForwardType a6) const {
PolymorphicInvoke f =
reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_);
diff --git a/base/callback.h.pump b/base/callback.h.pump
index 34b0eb0..542a84f 100644
--- a/base/callback.h.pump
+++ b/base/callback.h.pump
@@ -240,10 +240,10 @@ class Callback<R($for ARG , [[A$(ARG)]])> : public internal::CallbackBase {
]]
public:
- typedef R(*PolymorphicInvoke)(internal::InvokerStorageBase*[[]]
+ typedef R(*PolymorphicInvoke)(
+ internal::InvokerStorageBase*[[]]
$if ARITY != 0 [[, ]]
-$for ARG ,
- [[const A$(ARG)&]]);
+$for ARG , [[typename internal::ParamTraits<A$(ARG)>::ForwardType]]);
Callback() : CallbackBase(NULL, NULL) { }
@@ -262,7 +262,7 @@ $for ARG ,
}
R Run($for ARG ,
- [[const A$(ARG)& a$(ARG)]]) const {
+ [[typename internal::ParamTraits<A$(ARG)>::ForwardType a$(ARG)]]) const {
PolymorphicInvoke f =
reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_);
diff --git a/base/callback_internal.h b/base/callback_internal.h
index 4f1d3c3..b83b049 100644
--- a/base/callback_internal.h
+++ b/base/callback_internal.h
@@ -9,7 +9,10 @@
#define BASE_CALLBACK_INTERNAL_H_
#pragma once
-#include "base/ref_counted.h"
+#include <stddef.h>
+
+#include "base/base_api.h"
+#include "base/memory/ref_counted.h"
namespace base {
namespace internal {
@@ -51,7 +54,7 @@ InvokerStorageHolder<T> MakeInvokerStorageHolder(T* o) {
// Holds the Callback methods that don't require specialization to reduce
// template bloat.
-class CallbackBase {
+class BASE_API CallbackBase {
public:
// Returns true if Callback is null (doesn't refer to anything).
bool is_null() const;
@@ -80,6 +83,52 @@ class CallbackBase {
InvokeFuncStorage polymorphic_invoke_;
};
+// This is a typetraits object that's used to take an argument type, and
+// extract a suitable type for storing and forwarding arguments.
+//
+// In particular, it strips off references, and converts arrays to
+// pointers for storage; and it avoids accidentally trying to create a
+// "reference of a reference" if the argument is a reference type.
+//
+// This array type becomes an issue for storage because we are passing bound
+// parameters by const reference. In this case, we end up passing an actual
+// array type in the initializer list which C++ does not allow. This will
+// break passing of C-string literals.
+template <typename T>
+struct ParamTraits {
+ typedef const T& ForwardType;
+ typedef T StorageType;
+};
+
+// The Storage should almost be impossible to trigger unless someone manually
+// specifies type of the bind parameters. However, in case they do,
+// this will guard against us accidentally storing a reference parameter.
+//
+// The ForwardType should only be used for unbound arguments.
+template <typename T>
+struct ParamTraits<T&> {
+ typedef T& ForwardType;
+ typedef T StorageType;
+};
+
+// Note that for array types, we implicitly add a const in the conversion. This
+// means that it is not possible to bind array arguments to functions that take
+// a non-const pointer. Trying to specialize the template based on a "const
+// T[n]" does not seem to match correctly, so we are stuck with this
+// restriction.
+template <typename T, size_t n>
+struct ParamTraits<T[n]> {
+ typedef const T* ForwardType;
+ typedef const T* StorageType;
+};
+
+// See comment for ParamTraits<T[n]>.
+template <typename T>
+struct ParamTraits<T[]> {
+ typedef const T* ForwardType;
+ typedef const T* StorageType;
+};
+
} // namespace internal
} // namespace base
diff --git a/base/callback_old.h b/base/callback_old.h
index ab3927d..7719e66 100644
--- a/base/callback_old.h
+++ b/base/callback_old.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -6,8 +6,8 @@
#define BASE_CALLBACK_OLD_H_
#pragma once
+#include "base/memory/raw_scoped_refptr_mismatch_checker.h"
#include "base/tuple.h"
-#include "base/raw_scoped_refptr_mismatch_checker.h"
// Callback --------------------------------------------------------------------
//
diff --git a/base/callback_unittest.cc b/base/callback_unittest.cc
index f327412..da2f150 100644
--- a/base/callback_unittest.cc
+++ b/base/callback_unittest.cc
@@ -1,10 +1,10 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
#include "base/callback.h"
#include "base/callback_internal.h"
-#include "base/scoped_ptr.h"
+#include "base/memory/scoped_ptr.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/base/command_line.cc b/base/command_line.cc
index fcb2294..b027d2a 100644
--- a/base/command_line.cc
+++ b/base/command_line.cc
@@ -5,24 +5,19 @@
#include "base/command_line.h"
#include <algorithm>
+#include <ostream>
+#include "base/basictypes.h"
#include "base/file_path.h"
-#include "base/file_util.h"
#include "base/logging.h"
-#include "base/singleton.h"
#include "base/string_split.h"
#include "base/string_util.h"
-#include "base/sys_string_conversions.h"
#include "base/utf_string_conversions.h"
#include "build/build_config.h"
#if defined(OS_WIN)
#include <windows.h>
#include <shellapi.h>
-#elif defined(OS_POSIX)
-#include <limits.h>
-#include <stdlib.h>
-#include <unistd.h>
#endif
CommandLine* CommandLine::current_process_commandline_ = NULL;
diff --git a/base/command_line.h b/base/command_line.h
index 7ff5ab0..970e4a7 100644
--- a/base/command_line.h
+++ b/base/command_line.h
@@ -15,16 +15,17 @@
#define BASE_COMMAND_LINE_H_
#pragma once
+#include <stddef.h>
#include <map>
#include <string>
#include <vector>
-#include "base/basictypes.h"
+#include "base/base_api.h"
#include "build/build_config.h"
class FilePath;
-class CommandLine {
+class BASE_API CommandLine {
public:
#if defined(OS_WIN)
// The native command line string type.
diff --git a/base/compiler_specific.h b/base/compiler_specific.h
index 3060306..43ff21c 100644
--- a/base/compiler_specific.h
+++ b/base/compiler_specific.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -74,8 +74,10 @@
// int x ALLOW_UNUSED = ...;
#if defined(COMPILER_GCC)
#define ALLOW_UNUSED __attribute__((unused))
+#define NOINLINE __attribute__((noinline))
#else
#define ALLOW_UNUSED
+#define NOINLINE
#endif
// Annotate a virtual method indicating it must be overriding a virtual
diff --git a/base/cpu.cc b/base/cpu.cc
index 3232f15..f45e966 100644
--- a/base/cpu.cc
+++ b/base/cpu.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -120,6 +120,4 @@ void CPU::Initialize() {
#endif
}
-
-
} // namespace base
diff --git a/base/cpu.h b/base/cpu.h
index 1634bf9..22ec470 100644
--- a/base/cpu.h
+++ b/base/cpu.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -6,14 +6,14 @@
#define BASE_CPU_H_
#pragma once
-#include "build/build_config.h"
-
#include <string>
+#include "base/base_api.h"
+
namespace base {
// Query information about the processor.
-class CPU {
+class BASE_API CPU {
public:
// Constructor
CPU();
diff --git a/base/crypto/capi_util.cc b/base/crypto/capi_util.cc
deleted file mode 100644
index ef57a3c..0000000
--- a/base/crypto/capi_util.cc
+++ /dev/null
@@ -1,50 +0,0 @@
-// 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.
-
-#include "base/crypto/capi_util.h"
-
-#include "base/basictypes.h"
-#include "base/singleton.h"
-#include "base/synchronization/lock.h"
-
-namespace {
-
-class CAPIUtilSingleton {
- public:
- static CAPIUtilSingleton* GetInstance() {
- return Singleton<CAPIUtilSingleton>::get();
- }
-
- // Returns a lock to guard calls to CryptAcquireContext with
- // CRYPT_DELETEKEYSET or CRYPT_NEWKEYSET.
- base::Lock& acquire_context_lock() {
- return acquire_context_lock_;
- }
-
- private:
- friend class Singleton<CAPIUtilSingleton>;
- friend struct DefaultSingletonTraits<CAPIUtilSingleton>;
-
- CAPIUtilSingleton() {}
-
- base::Lock acquire_context_lock_;
-
- DISALLOW_COPY_AND_ASSIGN(CAPIUtilSingleton);
-};
-
-} // namespace
-
-namespace base {
-
-BOOL CryptAcquireContextLocked(HCRYPTPROV* prov,
- LPCWSTR container,
- LPCWSTR provider,
- DWORD prov_type,
- DWORD flags)
-{
- base::AutoLock lock(CAPIUtilSingleton::GetInstance()->acquire_context_lock());
- return CryptAcquireContext(prov, container, provider, prov_type, flags);
-}
-
-} // namespace base
diff --git a/base/crypto/capi_util.h b/base/crypto/capi_util.h
deleted file mode 100644
index df7f749..0000000
--- a/base/crypto/capi_util.h
+++ /dev/null
@@ -1,32 +0,0 @@
-// 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 BASE_CRYPTO_CAPI_UTIL_H_
-#define BASE_CRYPTO_CAPI_UTIL_H_
-#pragma once
-
-#include <windows.h>
-#include <wincrypt.h>
-
-namespace base {
-
-// CryptAcquireContext when passed CRYPT_NEWKEYSET or CRYPT_DELETEKEYSET in
-// flags is not thread-safe. For such calls, we create a global lock to
-// synchronize it.
-//
-// From "Threading Issues with Cryptographic Service Providers",
-// <http://msdn.microsoft.com/en-us/library/aa388149(v=VS.85).aspx>:
-//
-// "The CryptAcquireContext function is generally thread safe unless
-// CRYPT_NEWKEYSET or CRYPT_DELETEKEYSET is specified in the dwFlags
-// parameter."
-BOOL CryptAcquireContextLocked(HCRYPTPROV* prov,
- LPCWSTR container,
- LPCWSTR provider,
- DWORD prov_type,
- DWORD flags);
-
-} // namespace base
-
-#endif // BASE_CRYPTO_CAPI_UTIL_H_
diff --git a/base/crypto/crypto_module_blocking_password_delegate.h b/base/crypto/crypto_module_blocking_password_delegate.h
deleted file mode 100644
index ae962a8..0000000
--- a/base/crypto/crypto_module_blocking_password_delegate.h
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright (c) 2011 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 BASE_CRYPTO_CRYPTO_MODULE_BLOCKING_PASSWORD_DELEGATE_H_
-#define BASE_CRYPTO_CRYPTO_MODULE_BLOCKING_PASSWORD_DELEGATE_H_
-#pragma once
-
-#include <string>
-
-namespace base {
-
-// PK11_SetPasswordFunc is a global setting. An implementation of
-// CryptoModuleBlockingPasswordDelegate should be passed as the user data
-// argument (|wincx|) to relevant NSS functions, which the global password
-// handler will call to do the actual work.
-class CryptoModuleBlockingPasswordDelegate {
- public:
- virtual ~CryptoModuleBlockingPasswordDelegate() {}
-
- // Requests a password to unlock |slot_name|. The interface is
- // synchronous because NSS cannot issue an asynchronous
- // request. |retry| is true if this is a request for the retry
- // and we previously returned the wrong password.
- // The implementation should set |*cancelled| to true if the user cancelled
- // instead of entering a password, otherwise it should return the password the
- // user entered.
- virtual std::string RequestPassword(const std::string& slot_name, bool retry,
- bool* cancelled) = 0;
-};
-
-}
-
-#endif // BASE_CRYPTO_CRYPTO_MODULE_BLOCKING_PASSWORD_DELEGATE_H_
diff --git a/base/crypto/cssm_init.cc b/base/crypto/cssm_init.cc
deleted file mode 100644
index 570dcc3..0000000
--- a/base/crypto/cssm_init.cc
+++ /dev/null
@@ -1,231 +0,0 @@
-// Copyright (c) 2009 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.
-
-#include "base/crypto/cssm_init.h"
-
-#include <Security/SecBase.h>
-
-#include "base/logging.h"
-#include "base/mac/scoped_cftyperef.h"
-#include "base/singleton.h"
-#include "base/synchronization/lock.h"
-#include "base/sys_string_conversions.h"
-
-// When writing crypto code for Mac OS X, you may find the following
-// documentation useful:
-// - Common Security: CDSA and CSSM, Version 2 (with corrigenda)
-// http://www.opengroup.org/security/cdsa.htm
-// - Apple Cryptographic Service Provider Functional Specification
-// - CryptoSample: http://developer.apple.com/SampleCode/CryptoSample/
-
-namespace {
-
-void* CSSMMalloc(CSSM_SIZE size, void* alloc_ref) {
- return malloc(size);
-}
-
-void CSSMFree(void* mem_ptr, void* alloc_ref) {
- free(mem_ptr);
-}
-
-void* CSSMRealloc(void* ptr, CSSM_SIZE size, void* alloc_ref) {
- return realloc(ptr, size);
-}
-
-void* CSSMCalloc(uint32 num, CSSM_SIZE size, void* alloc_ref) {
- return calloc(num, size);
-}
-
-class CSSMInitSingleton {
- public:
- static CSSMInitSingleton* GetInstance() {
- return Singleton<CSSMInitSingleton,
- LeakySingletonTraits<CSSMInitSingleton> >::get();
- }
-
- CSSM_CSP_HANDLE csp_handle() const { return csp_handle_; }
- CSSM_CL_HANDLE cl_handle() const { return cl_handle_; }
- CSSM_TP_HANDLE tp_handle() const { return tp_handle_; }
-
- private:
- CSSMInitSingleton()
- : inited_(false), csp_loaded_(false), cl_loaded_(false),
- tp_loaded_(false), csp_handle_(NULL), cl_handle_(NULL),
- tp_handle_(NULL) {
- static CSSM_VERSION version = {2, 0};
- // TODO(wtc): what should our caller GUID be?
- static const CSSM_GUID test_guid = {
- 0xFADE, 0, 0, { 1, 2, 3, 4, 5, 6, 7, 0 }
- };
- CSSM_RETURN crtn;
- CSSM_PVC_MODE pvc_policy = CSSM_PVC_NONE;
- crtn = CSSM_Init(&version, CSSM_PRIVILEGE_SCOPE_NONE, &test_guid,
- CSSM_KEY_HIERARCHY_NONE, &pvc_policy, NULL);
- if (crtn) {
- NOTREACHED();
- return;
- }
- inited_ = true;
-
- crtn = CSSM_ModuleLoad(&gGuidAppleCSP, CSSM_KEY_HIERARCHY_NONE, NULL, NULL);
- if (crtn) {
- NOTREACHED();
- return;
- }
- csp_loaded_ = true;
- crtn = CSSM_ModuleLoad(
- &gGuidAppleX509CL, CSSM_KEY_HIERARCHY_NONE, NULL, NULL);
- if (crtn) {
- NOTREACHED();
- return;
- }
- cl_loaded_ = true;
- crtn = CSSM_ModuleLoad(
- &gGuidAppleX509TP, CSSM_KEY_HIERARCHY_NONE, NULL, NULL);
- if (crtn) {
- NOTREACHED();
- return;
- }
- tp_loaded_ = true;
-
- const CSSM_API_MEMORY_FUNCS cssmMemoryFunctions = {
- CSSMMalloc,
- CSSMFree,
- CSSMRealloc,
- CSSMCalloc,
- NULL
- };
-
- crtn = CSSM_ModuleAttach(&gGuidAppleCSP, &version, &cssmMemoryFunctions, 0,
- CSSM_SERVICE_CSP, 0, CSSM_KEY_HIERARCHY_NONE,
- NULL, 0, NULL, &csp_handle_);
- DCHECK(crtn == CSSM_OK);
- crtn = CSSM_ModuleAttach(&gGuidAppleX509CL, &version, &cssmMemoryFunctions,
- 0, CSSM_SERVICE_CL, 0, CSSM_KEY_HIERARCHY_NONE,
- NULL, 0, NULL, &cl_handle_);
- DCHECK(crtn == CSSM_OK);
- crtn = CSSM_ModuleAttach(&gGuidAppleX509TP, &version, &cssmMemoryFunctions,
- 0, CSSM_SERVICE_TP, 0, CSSM_KEY_HIERARCHY_NONE,
- NULL, 0, NULL, &tp_handle_);
- DCHECK(crtn == CSSM_OK);
- }
-
- ~CSSMInitSingleton() {
- CSSM_RETURN crtn;
- if (csp_handle_) {
- CSSM_RETURN crtn = CSSM_ModuleDetach(csp_handle_);
- DCHECK(crtn == CSSM_OK);
- }
- if (cl_handle_) {
- CSSM_RETURN crtn = CSSM_ModuleDetach(cl_handle_);
- DCHECK(crtn == CSSM_OK);
- }
- if (tp_handle_) {
- CSSM_RETURN crtn = CSSM_ModuleDetach(tp_handle_);
- DCHECK(crtn == CSSM_OK);
- }
- if (csp_loaded_) {
- crtn = CSSM_ModuleUnload(&gGuidAppleCSP, NULL, NULL);
- DCHECK(crtn == CSSM_OK);
- }
- if (cl_loaded_) {
- crtn = CSSM_ModuleUnload(&gGuidAppleX509CL, NULL, NULL);
- DCHECK(crtn == CSSM_OK);
- }
- if (tp_loaded_) {
- crtn = CSSM_ModuleUnload(&gGuidAppleX509TP, NULL, NULL);
- DCHECK(crtn == CSSM_OK);
- }
- if (inited_) {
- crtn = CSSM_Terminate();
- DCHECK(crtn == CSSM_OK);
- }
- }
-
- bool inited_; // True if CSSM_Init has been called successfully.
- bool csp_loaded_; // True if gGuidAppleCSP has been loaded
- bool cl_loaded_; // True if gGuidAppleX509CL has been loaded.
- bool tp_loaded_; // True if gGuidAppleX509TP has been loaded.
- CSSM_CSP_HANDLE csp_handle_;
- CSSM_CL_HANDLE cl_handle_;
- CSSM_TP_HANDLE tp_handle_;
-
- friend struct DefaultSingletonTraits<CSSMInitSingleton>;
-};
-
-// This singleton is separate as it pertains to Apple's wrappers over
-// their own CSSM handles, as opposed to our own CSSM_CSP_HANDLE.
-class SecurityServicesSingleton {
- public:
- static SecurityServicesSingleton* GetInstance() {
- return Singleton<SecurityServicesSingleton,
- LeakySingletonTraits<SecurityServicesSingleton> >::get();
- }
-
- base::Lock& lock() { return lock_; }
-
- private:
- friend struct DefaultSingletonTraits<SecurityServicesSingleton>;
-
- SecurityServicesSingleton() {}
- ~SecurityServicesSingleton() {}
-
- base::Lock lock_;
-
- DISALLOW_COPY_AND_ASSIGN(SecurityServicesSingleton);
-};
-
-} // namespace
-
-namespace base {
-
-void EnsureCSSMInit() {
- CSSMInitSingleton::GetInstance();
-}
-
-CSSM_CSP_HANDLE GetSharedCSPHandle() {
- return CSSMInitSingleton::GetInstance()->csp_handle();
-}
-
-CSSM_CL_HANDLE GetSharedCLHandle() {
- return CSSMInitSingleton::GetInstance()->cl_handle();
-}
-
-CSSM_TP_HANDLE GetSharedTPHandle() {
- return CSSMInitSingleton::GetInstance()->tp_handle();
-}
-
-void* CSSMMalloc(CSSM_SIZE size) {
- return ::CSSMMalloc(size, NULL);
-}
-
-void CSSMFree(void* ptr) {
- ::CSSMFree(ptr, NULL);
-}
-
-void LogCSSMError(const char* fn_name, CSSM_RETURN err) {
- if (!err)
- return;
- base::mac::ScopedCFTypeRef<CFStringRef> cfstr(
- SecCopyErrorMessageString(err, NULL));
- LOG(ERROR) << fn_name << " returned " << err
- << " (" << SysCFStringRefToUTF8(cfstr) << ")";
-}
-
-base::Lock& GetMacSecurityServicesLock() {
- return SecurityServicesSingleton::GetInstance()->lock();
-}
-
-ScopedCSSMData::ScopedCSSMData() {
- memset(&data_, 0, sizeof(data_));
-}
-
-ScopedCSSMData::~ScopedCSSMData() {
- if (data_.Data) {
- CSSMFree(data_.Data);
- data_.Data = NULL;
- }
-}
-
-} // namespace base
diff --git a/base/crypto/cssm_init.h b/base/crypto/cssm_init.h
deleted file mode 100644
index b51a3b5..0000000
--- a/base/crypto/cssm_init.h
+++ /dev/null
@@ -1,69 +0,0 @@
-// 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 BASE_CRYPTO_CSSM_INIT_H_
-#define BASE_CRYPTO_CSSM_INIT_H_
-#pragma once
-
-#include <Security/cssm.h>
-
-#include "base/basictypes.h"
-
-namespace base {
-
-class Lock;
-
-// Initialize CSSM if it isn't already initialized. This must be called before
-// any other CSSM functions. This function is thread-safe, and CSSM will only
-// ever be initialized once. CSSM will be properly shut down on program exit.
-void EnsureCSSMInit();
-
-// Returns the shared CSP handle used by CSSM functions.
-CSSM_CSP_HANDLE GetSharedCSPHandle();
-
-// Returns the shared CL handle used by CSSM functions.
-CSSM_CL_HANDLE GetSharedCLHandle();
-
-// Returns the shared TP handle used by CSSM functions.
-CSSM_TP_HANDLE GetSharedTPHandle();
-
-// Set of pointers to memory function wrappers that are required for CSSM
-extern const CSSM_API_MEMORY_FUNCS kCssmMemoryFunctions;
-
-// Utility function to log an error message including the error name.
-void LogCSSMError(const char *function_name, CSSM_RETURN err);
-
-// Utility functions to allocate and release CSSM memory.
-void* CSSMMalloc(CSSM_SIZE size);
-void CSSMFree(void* ptr);
-
-// The OS X certificate and key management wrappers over CSSM are not
-// thread-safe. In particular, code that accesses the CSSM database is
-// problematic.
-//
-// http://developer.apple.com/mac/library/documentation/Security/Reference/certifkeytrustservices/Reference/reference.html
-Lock& GetMacSecurityServicesLock();
-
-// Wrapper class for CSSM_DATA type. This should only be used when using the
-// CL/TP/CSP handles from above, since that's the only time we're guaranteed (or
-// supposed to be guaranteed) that our memory management functions will be used.
-// Apple's Sec* APIs manage their own memory so it shouldn't be used for those.
-// The constructor initializes data_ to zero and the destructor releases the
-// data properly.
-class ScopedCSSMData {
- public:
- ScopedCSSMData();
- ~ScopedCSSMData();
- operator CSSM_DATA*() { return &data_; }
- CSSM_DATA* operator ->() { return &data_; }
-
- private:
- CSSM_DATA data_;
-
- DISALLOW_COPY_AND_ASSIGN(ScopedCSSMData);
-};
-
-} // namespace base
-
-#endif // BASE_CRYPTO_CSSM_INIT_H_
diff --git a/base/crypto/encryptor.h b/base/crypto/encryptor.h
deleted file mode 100644
index 7718240..0000000
--- a/base/crypto/encryptor.h
+++ /dev/null
@@ -1,69 +0,0 @@
-// 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 BASE_CRYPTO_ENCRYPTOR_H_
-#define BASE_CRYPTO_ENCRYPTOR_H_
-#pragma once
-
-#include <string>
-
-#include "build/build_config.h"
-
-#if defined(USE_NSS)
-#include "base/crypto/scoped_nss_types.h"
-#elif defined(OS_WIN)
-#include "base/crypto/scoped_capi_types.h"
-#endif
-
-namespace base {
-
-class SymmetricKey;
-
-class Encryptor {
- public:
- enum Mode {
- CBC
- };
- Encryptor();
- virtual ~Encryptor();
-
- // Initializes the encryptor using |key| and |iv|. Returns false if either the
- // key or the initialization vector cannot be used.
- bool Init(SymmetricKey* key, Mode mode, const std::string& iv);
-
- // Encrypts |plaintext| into |ciphertext|.
- bool Encrypt(const std::string& plaintext, std::string* ciphertext);
-
- // Decrypts |ciphertext| into |plaintext|.
- bool Decrypt(const std::string& ciphertext, std::string* plaintext);
-
- // TODO(albertb): Support streaming encryption.
-
- private:
- SymmetricKey* key_;
- Mode mode_;
-
-#if defined(USE_OPENSSL)
- bool Crypt(bool encrypt, // Pass true to encrypt, false to decrypt.
- const std::string& input,
- std::string* output);
- std::string iv_;
-#elif defined(USE_NSS)
- ScopedPK11Slot slot_;
- ScopedSECItem param_;
-#elif defined(OS_MACOSX)
- bool Crypt(int /*CCOperation*/ op,
- const std::string& input,
- std::string* output);
-
- std::string iv_;
-#elif defined(OS_WIN)
- ScopedHCRYPTKEY capi_key_;
- DWORD block_size_;
-#endif
-};
-
-} // namespace base
-
-#endif // BASE_CRYPTO_ENCRYPTOR_H_
diff --git a/base/crypto/encryptor_mac.cc b/base/crypto/encryptor_mac.cc
deleted file mode 100644
index e26c6bd..0000000
--- a/base/crypto/encryptor_mac.cc
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright (c) 2011 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.
-
-#include "base/crypto/encryptor.h"
-
-#include <CommonCrypto/CommonCryptor.h>
-
-#include "base/crypto/symmetric_key.h"
-#include "base/logging.h"
-#include "base/string_util.h"
-
-namespace base {
-
-Encryptor::Encryptor()
- : key_(NULL),
- mode_(CBC) {
-}
-
-Encryptor::~Encryptor() {
-}
-
-bool Encryptor::Init(SymmetricKey* key, Mode mode, const std::string& iv) {
- DCHECK(key);
- DCHECK_EQ(CBC, mode) << "Unsupported mode of operation";
- CSSM_DATA raw_key = key->cssm_data();
- if (raw_key.Length != kCCKeySizeAES128 &&
- raw_key.Length != kCCKeySizeAES192 &&
- raw_key.Length != kCCKeySizeAES256)
- return false;
- if (iv.size() != kCCBlockSizeAES128)
- return false;
-
- key_ = key;
- mode_ = mode;
- iv_ = iv;
- return true;
-}
-
-bool Encryptor::Crypt(int /*CCOperation*/ op,
- const std::string& input,
- std::string* output) {
- DCHECK(key_);
- CSSM_DATA raw_key = key_->cssm_data();
- // CommonCryptor.h: "A general rule for the size of the output buffer which
- // must be provided by the caller is that for block ciphers, the output
- // length is never larger than the input length plus the block size."
-
- size_t output_size = input.size() + iv_.size();
- CCCryptorStatus err = CCCrypt(op,
- kCCAlgorithmAES128,
- kCCOptionPKCS7Padding,
- raw_key.Data, raw_key.Length,
- iv_.data(),
- input.data(), input.size(),
- WriteInto(output, output_size+1),
- output_size,
- &output_size);
- if (err) {
- output->resize(0);
- LOG(ERROR) << "CCCrypt returned " << err;
- return false;
- }
- output->resize(output_size);
- return true;
-}
-
-bool Encryptor::Encrypt(const std::string& plaintext, std::string* ciphertext) {
- return Crypt(kCCEncrypt, plaintext, ciphertext);
-}
-
-bool Encryptor::Decrypt(const std::string& ciphertext, std::string* plaintext) {
- return Crypt(kCCDecrypt, ciphertext, plaintext);
-}
-
-} // namespace base
diff --git a/base/crypto/encryptor_nss.cc b/base/crypto/encryptor_nss.cc
deleted file mode 100644
index 3b9f7f3..0000000
--- a/base/crypto/encryptor_nss.cc
+++ /dev/null
@@ -1,125 +0,0 @@
-// Copyright (c) 2011 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.
-
-#include "base/crypto/encryptor.h"
-
-#include <cryptohi.h>
-#include <vector>
-
-#include "base/crypto/symmetric_key.h"
-#include "base/logging.h"
-#include "base/nss_util.h"
-
-namespace base {
-
-Encryptor::Encryptor()
- : key_(NULL),
- mode_(CBC) {
- EnsureNSSInit();
-}
-
-Encryptor::~Encryptor() {
-}
-
-bool Encryptor::Init(SymmetricKey* key, Mode mode, const std::string& iv) {
- DCHECK(key);
- DCHECK_EQ(CBC, mode);
-
- key_ = key;
- mode_ = mode;
-
- if (iv.size() != AES_BLOCK_SIZE)
- return false;
-
- slot_.reset(PK11_GetBestSlot(CKM_AES_CBC_PAD, NULL));
- if (!slot_.get())
- return false;
-
- SECItem iv_item;
- iv_item.type = siBuffer;
- iv_item.data = reinterpret_cast<unsigned char*>(
- const_cast<char *>(iv.data()));
- iv_item.len = iv.size();
-
- param_.reset(PK11_ParamFromIV(CKM_AES_CBC_PAD, &iv_item));
- if (!param_.get())
- return false;
-
- return true;
-}
-
-bool Encryptor::Encrypt(const std::string& plaintext, std::string* ciphertext) {
- ScopedPK11Context context(PK11_CreateContextBySymKey(CKM_AES_CBC_PAD,
- CKA_ENCRYPT,
- key_->key(),
- param_.get()));
- if (!context.get())
- return false;
-
- size_t ciphertext_len = plaintext.size() + AES_BLOCK_SIZE;
- std::vector<unsigned char> buffer(ciphertext_len);
-
- int op_len;
- SECStatus rv = PK11_CipherOp(context.get(),
- &buffer[0],
- &op_len,
- ciphertext_len,
- reinterpret_cast<unsigned char*>(
- const_cast<char*>(plaintext.data())),
- plaintext.size());
- if (SECSuccess != rv)
- return false;
-
- unsigned int digest_len;
- rv = PK11_DigestFinal(context.get(),
- &buffer[op_len],
- &digest_len,
- ciphertext_len - op_len);
- if (SECSuccess != rv)
- return false;
-
- ciphertext->assign(reinterpret_cast<char *>(&buffer[0]),
- op_len + digest_len);
- return true;
-}
-
-bool Encryptor::Decrypt(const std::string& ciphertext, std::string* plaintext) {
- if (ciphertext.empty())
- return false;
-
- ScopedPK11Context context(PK11_CreateContextBySymKey(CKM_AES_CBC_PAD,
- CKA_DECRYPT,
- key_->key(),
- param_.get()));
- if (!context.get())
- return false;
-
- size_t plaintext_len = ciphertext.size();
- std::vector<unsigned char> buffer(plaintext_len);
-
- int op_len;
- SECStatus rv = PK11_CipherOp(context.get(),
- &buffer[0],
- &op_len,
- plaintext_len,
- reinterpret_cast<unsigned char*>(
- const_cast<char*>(ciphertext.data())),
- ciphertext.size());
- if (SECSuccess != rv)
- return false;
-
- unsigned int digest_len;
- rv = PK11_DigestFinal(context.get(),
- &buffer[op_len],
- &digest_len,
- plaintext_len - op_len);
- if (SECSuccess != rv)
- return false;
-
- plaintext->assign(reinterpret_cast<char *>(&buffer[0]),
- op_len + digest_len);
- return true;
-}
-
-} // namespace base
diff --git a/base/crypto/encryptor_openssl.cc b/base/crypto/encryptor_openssl.cc
deleted file mode 100644
index 0e101a0..0000000
--- a/base/crypto/encryptor_openssl.cc
+++ /dev/null
@@ -1,127 +0,0 @@
-// Copyright (c) 2011 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.
-
-#include "base/crypto/encryptor.h"
-
-#include <openssl/aes.h>
-#include <openssl/evp.h>
-
-#include "base/crypto/symmetric_key.h"
-#include "base/logging.h"
-#include "base/openssl_util.h"
-#include "base/string_util.h"
-
-namespace base {
-
-namespace {
-
-const EVP_CIPHER* GetCipherForKey(SymmetricKey* key) {
- switch (key->key().length()) {
- case 16: return EVP_aes_128_cbc();
- case 24: return EVP_aes_192_cbc();
- case 32: return EVP_aes_256_cbc();
- default: return NULL;
- }
-}
-
-// On destruction this class will cleanup the ctx, and also clear the OpenSSL
-// ERR stack as a convenience.
-class ScopedCipherCTX {
- public:
- explicit ScopedCipherCTX() {
- EVP_CIPHER_CTX_init(&ctx_);
- }
- ~ScopedCipherCTX() {
- EVP_CIPHER_CTX_cleanup(&ctx_);
- ClearOpenSSLERRStack(FROM_HERE);
- }
- EVP_CIPHER_CTX* get() { return &ctx_; }
-
- private:
- EVP_CIPHER_CTX ctx_;
-};
-
-} // namespace
-
-Encryptor::Encryptor()
- : key_(NULL),
- mode_(CBC) {
-}
-
-Encryptor::~Encryptor() {
-}
-
-bool Encryptor::Init(SymmetricKey* key, Mode mode, const std::string& iv) {
- DCHECK(key);
- DCHECK_EQ(CBC, mode);
-
- EnsureOpenSSLInit();
- if (iv.size() != AES_BLOCK_SIZE)
- return false;
-
- if (GetCipherForKey(key) == NULL)
- return false;
-
- key_ = key;
- mode_ = mode;
- iv_ = iv;
- return true;
-}
-
-bool Encryptor::Encrypt(const std::string& plaintext, std::string* ciphertext) {
- return Crypt(true, plaintext, ciphertext);
-}
-
-bool Encryptor::Decrypt(const std::string& ciphertext, std::string* plaintext) {
- return Crypt(false, ciphertext, plaintext);
-}
-
-bool Encryptor::Crypt(bool do_encrypt,
- const std::string& input,
- std::string* output) {
- DCHECK(key_); // Must call Init() before En/De-crypt.
- // Work on the result in a local variable, and then only transfer it to
- // |output| on success to ensure no partial data is returned.
- std::string result;
- output->swap(result);
-
- const EVP_CIPHER* cipher = GetCipherForKey(key_);
- DCHECK(cipher); // Already handled in Init();
-
- const std::string& key = key_->key();
- DCHECK_EQ(EVP_CIPHER_iv_length(cipher), static_cast<int>(iv_.length()));
- DCHECK_EQ(EVP_CIPHER_key_length(cipher), static_cast<int>(key.length()));
-
- ScopedCipherCTX ctx;
- if (!EVP_CipherInit_ex(ctx.get(), cipher, NULL,
- reinterpret_cast<const uint8*>(key.data()),
- reinterpret_cast<const uint8*>(iv_.data()),
- do_encrypt))
- return false;
-
- // When encrypting, add another block size of space to allow for any padding.
- const size_t output_size = input.size() + (do_encrypt ? iv_.size() : 0);
- uint8* out_ptr = reinterpret_cast<uint8*>(WriteInto(&result,
- output_size + 1));
- int out_len;
- if (!EVP_CipherUpdate(ctx.get(), out_ptr, &out_len,
- reinterpret_cast<const uint8*>(input.data()),
- input.length()))
- return false;
-
- // Write out the final block plus padding (if any) to the end of the data
- // just written.
- int tail_len;
- if (!EVP_CipherFinal_ex(ctx.get(), out_ptr + out_len, &tail_len))
- return false;
-
- out_len += tail_len;
- DCHECK_LE(out_len, static_cast<int>(output_size));
- result.resize(out_len);
-
- output->swap(result);
- return true;
-}
-
-} // namespace base
diff --git a/base/crypto/encryptor_unittest.cc b/base/crypto/encryptor_unittest.cc
deleted file mode 100644
index e8d055b..0000000
--- a/base/crypto/encryptor_unittest.cc
+++ /dev/null
@@ -1,232 +0,0 @@
-// 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.
-
-#include "base/crypto/encryptor.h"
-
-#include <string>
-
-#include "base/crypto/symmetric_key.h"
-#include "base/scoped_ptr.h"
-#include "base/string_number_conversions.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-TEST(EncryptorTest, EncryptDecrypt) {
- scoped_ptr<base::SymmetricKey> key(base::SymmetricKey::DeriveKeyFromPassword(
- base::SymmetricKey::AES, "password", "saltiest", 1000, 256));
- EXPECT_TRUE(NULL != key.get());
-
- base::Encryptor encryptor;
- // The IV must be exactly as long as the cipher block size.
- std::string iv("the iv: 16 bytes");
- EXPECT_EQ(16U, iv.size());
- EXPECT_TRUE(encryptor.Init(key.get(), base::Encryptor::CBC, iv));
-
- std::string plaintext("this is the plaintext");
- std::string ciphertext;
- EXPECT_TRUE(encryptor.Encrypt(plaintext, &ciphertext));
-
- EXPECT_LT(0U, ciphertext.size());
-
- std::string decypted;
- EXPECT_TRUE(encryptor.Decrypt(ciphertext, &decypted));
-
- EXPECT_EQ(plaintext, decypted);
-}
-
-// TODO(wtc): add more known-answer tests. Test vectors are available from
-// http://www.ietf.org/rfc/rfc3602
-// http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
-// http://gladman.plushost.co.uk/oldsite/AES/index.php
-// http://csrc.nist.gov/groups/STM/cavp/documents/aes/KAT_AES.zip
-
-// NIST SP 800-38A test vector F.2.5 CBC-AES256.Encrypt.
-TEST(EncryptorTest, EncryptAES256CBC) {
- // From NIST SP 800-38a test cast F.2.5 CBC-AES256.Encrypt.
- static const unsigned char raw_key[] = {
- 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe,
- 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
- 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7,
- 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4
- };
- static const unsigned char raw_iv[] = {
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
- };
- static const unsigned char raw_plaintext[] = {
- // Block #1
- 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
- 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
- // Block #2
- 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
- 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
- // Block #3
- 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
- 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
- // Block #4
- 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
- 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10,
- };
- static const unsigned char raw_ciphertext[] = {
- // Block #1
- 0xf5, 0x8c, 0x4c, 0x04, 0xd6, 0xe5, 0xf1, 0xba,
- 0x77, 0x9e, 0xab, 0xfb, 0x5f, 0x7b, 0xfb, 0xd6,
- // Block #2
- 0x9c, 0xfc, 0x4e, 0x96, 0x7e, 0xdb, 0x80, 0x8d,
- 0x67, 0x9f, 0x77, 0x7b, 0xc6, 0x70, 0x2c, 0x7d,
- // Block #3
- 0x39, 0xf2, 0x33, 0x69, 0xa9, 0xd9, 0xba, 0xcf,
- 0xa5, 0x30, 0xe2, 0x63, 0x04, 0x23, 0x14, 0x61,
- // Block #4
- 0xb2, 0xeb, 0x05, 0xe2, 0xc3, 0x9b, 0xe9, 0xfc,
- 0xda, 0x6c, 0x19, 0x07, 0x8c, 0x6a, 0x9d, 0x1b,
- // PKCS #5 padding, encrypted.
- 0x3f, 0x46, 0x17, 0x96, 0xd6, 0xb0, 0xd6, 0xb2,
- 0xe0, 0xc2, 0xa7, 0x2b, 0x4d, 0x80, 0xe6, 0x44
- };
-
- std::string key(reinterpret_cast<const char*>(raw_key), sizeof(raw_key));
- scoped_ptr<base::SymmetricKey> sym_key(base::SymmetricKey::Import(
- base::SymmetricKey::AES, key));
- ASSERT_TRUE(NULL != sym_key.get());
-
- base::Encryptor encryptor;
- // The IV must be exactly as long a the cipher block size.
- std::string iv(reinterpret_cast<const char*>(raw_iv), sizeof(raw_iv));
- EXPECT_EQ(16U, iv.size());
- EXPECT_TRUE(encryptor.Init(sym_key.get(), base::Encryptor::CBC, iv));
-
- std::string plaintext(reinterpret_cast<const char*>(raw_plaintext),
- sizeof(raw_plaintext));
- std::string ciphertext;
- EXPECT_TRUE(encryptor.Encrypt(plaintext, &ciphertext));
-
- EXPECT_EQ(sizeof(raw_ciphertext), ciphertext.size());
- EXPECT_EQ(0, memcmp(ciphertext.data(), raw_ciphertext, ciphertext.size()));
-
- std::string decypted;
- EXPECT_TRUE(encryptor.Decrypt(ciphertext, &decypted));
-
- EXPECT_EQ(plaintext, decypted);
-}
-
-// Expected output derived from the NSS implementation.
-TEST(EncryptorTest, EncryptAES128CBCRegression) {
- std::string key = "128=SixteenBytes";
- std::string iv = "Sweet Sixteen IV";
- std::string plaintext = "Plain text with a g-clef U+1D11E \360\235\204\236";
- std::string expected_ciphertext_hex =
- "D4A67A0BA33C30F207344D81D1E944BBE65587C3D7D9939A"
- "C070C62B9C15A3EA312EA4AD1BC7929F4D3C16B03AD5ADA8";
-
- scoped_ptr<base::SymmetricKey> sym_key(base::SymmetricKey::Import(
- base::SymmetricKey::AES, key));
- ASSERT_TRUE(NULL != sym_key.get());
-
- base::Encryptor encryptor;
- // The IV must be exactly as long a the cipher block size.
- EXPECT_EQ(16U, iv.size());
- EXPECT_TRUE(encryptor.Init(sym_key.get(), base::Encryptor::CBC, iv));
-
- std::string ciphertext;
- EXPECT_TRUE(encryptor.Encrypt(plaintext, &ciphertext));
- EXPECT_EQ(expected_ciphertext_hex, base::HexEncode(ciphertext.data(),
- ciphertext.size()));
-
- std::string decypted;
- EXPECT_TRUE(encryptor.Decrypt(ciphertext, &decypted));
- EXPECT_EQ(plaintext, decypted);
-}
-
-// Expected output derived from the NSS implementation.
-TEST(EncryptorTest, EncryptAES192CBCRegression) {
- std::string key = "192bitsIsTwentyFourByte!";
- std::string iv = "Sweet Sixteen IV";
- std::string plaintext = "Small text";
- std::string expected_ciphertext_hex = "78DE5D7C2714FC5C61346C5416F6C89A";
-
- scoped_ptr<base::SymmetricKey> sym_key(base::SymmetricKey::Import(
- base::SymmetricKey::AES, key));
- ASSERT_TRUE(NULL != sym_key.get());
-
- base::Encryptor encryptor;
- // The IV must be exactly as long a the cipher block size.
- EXPECT_EQ(16U, iv.size());
- EXPECT_TRUE(encryptor.Init(sym_key.get(), base::Encryptor::CBC, iv));
-
- std::string ciphertext;
- EXPECT_TRUE(encryptor.Encrypt(plaintext, &ciphertext));
- EXPECT_EQ(expected_ciphertext_hex, base::HexEncode(ciphertext.data(),
- ciphertext.size()));
-
- std::string decypted;
- EXPECT_TRUE(encryptor.Decrypt(ciphertext, &decypted));
- EXPECT_EQ(plaintext, decypted);
-}
-
-// Not all platforms allow import/generation of symmetric keys with an
-// unsupported size.
-#if !defined(OS_WIN) && !defined(USE_NSS)
-TEST(EncryptorTest, UnsupportedKeySize) {
- std::string key = "7 = bad";
- std::string iv = "Sweet Sixteen IV";
- scoped_ptr<base::SymmetricKey> sym_key(base::SymmetricKey::Import(
- base::SymmetricKey::AES, key));
- ASSERT_TRUE(NULL != sym_key.get());
-
- base::Encryptor encryptor;
- // The IV must be exactly as long a the cipher block size.
- EXPECT_EQ(16U, iv.size());
- EXPECT_FALSE(encryptor.Init(sym_key.get(), base::Encryptor::CBC, iv));
-}
-#endif // unsupported platforms.
-
-TEST(EncryptorTest, UnsupportedIV) {
- std::string key = "128=SixteenBytes";
- std::string iv = "OnlyForteen :(";
- scoped_ptr<base::SymmetricKey> sym_key(base::SymmetricKey::Import(
- base::SymmetricKey::AES, key));
- ASSERT_TRUE(NULL != sym_key.get());
-
- base::Encryptor encryptor;
- EXPECT_FALSE(encryptor.Init(sym_key.get(), base::Encryptor::CBC, iv));
-}
-
-TEST(EncryptorTest, EmptyEncrypt) {
- std::string key = "128=SixteenBytes";
- std::string iv = "Sweet Sixteen IV";
- std::string plaintext;
- std::string expected_ciphertext_hex = "8518B8878D34E7185E300D0FCC426396";
-
- scoped_ptr<base::SymmetricKey> sym_key(base::SymmetricKey::Import(
- base::SymmetricKey::AES, key));
- ASSERT_TRUE(NULL != sym_key.get());
-
- base::Encryptor encryptor;
- // The IV must be exactly as long a the cipher block size.
- EXPECT_EQ(16U, iv.size());
- EXPECT_TRUE(encryptor.Init(sym_key.get(), base::Encryptor::CBC, iv));
-
- std::string ciphertext;
- EXPECT_TRUE(encryptor.Encrypt(plaintext, &ciphertext));
- EXPECT_EQ(expected_ciphertext_hex, base::HexEncode(ciphertext.data(),
- ciphertext.size()));
-}
-
-TEST(EncryptorTest, EmptyDecrypt) {
- std::string key = "128=SixteenBytes";
- std::string iv = "Sweet Sixteen IV";
-
- scoped_ptr<base::SymmetricKey> sym_key(base::SymmetricKey::Import(
- base::SymmetricKey::AES, key));
- ASSERT_TRUE(NULL != sym_key.get());
-
- base::Encryptor encryptor;
- // The IV must be exactly as long a the cipher block size.
- EXPECT_EQ(16U, iv.size());
- EXPECT_TRUE(encryptor.Init(sym_key.get(), base::Encryptor::CBC, iv));
-
- std::string decrypted;
- EXPECT_FALSE(encryptor.Decrypt("", &decrypted));
- EXPECT_EQ("", decrypted);
-}
diff --git a/base/crypto/encryptor_win.cc b/base/crypto/encryptor_win.cc
deleted file mode 100644
index 1d732b5..0000000
--- a/base/crypto/encryptor_win.cc
+++ /dev/null
@@ -1,115 +0,0 @@
-// Copyright (c) 2011 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.
-
-#include "base/crypto/encryptor.h"
-
-#include <vector>
-
-#include "base/crypto/symmetric_key.h"
-
-namespace base {
-
-namespace {
-
-// On success, returns the block size (in bytes) for the algorithm that |key|
-// is for. On failure, returns 0.
-DWORD GetCipherBlockSize(HCRYPTKEY key) {
- DWORD block_size_in_bits = 0;
- DWORD param_size = sizeof(block_size_in_bits);
- BOOL ok = CryptGetKeyParam(key, KP_BLOCKLEN,
- reinterpret_cast<BYTE*>(&block_size_in_bits),
- &param_size, 0);
- if (!ok)
- return 0;
-
- return block_size_in_bits / 8;
-}
-
-} // namespace
-
-Encryptor::Encryptor()
- : key_(NULL),
- mode_(CBC),
- block_size_(0) {
-}
-
-Encryptor::~Encryptor() {
-}
-
-bool Encryptor::Init(SymmetricKey* key, Mode mode, const std::string& iv) {
- DCHECK(key);
- DCHECK_EQ(CBC, mode) << "Unsupported mode of operation";
-
- // In CryptoAPI, the IV, padding mode, and feedback register (for a chaining
- // mode) are properties of a key, so we have to create a copy of the key for
- // the Encryptor. See the Remarks section of the CryptEncrypt MSDN page.
- BOOL ok = CryptDuplicateKey(key->key(), NULL, 0, capi_key_.receive());
- if (!ok)
- return false;
-
- // CRYPT_MODE_CBC is the default for Microsoft Base Cryptographic Provider,
- // but we set it anyway to be safe.
- DWORD cipher_mode = CRYPT_MODE_CBC;
- ok = CryptSetKeyParam(capi_key_.get(), KP_MODE,
- reinterpret_cast<BYTE*>(&cipher_mode), 0);
- if (!ok)
- return false;
-
- block_size_ = GetCipherBlockSize(capi_key_.get());
- if (block_size_ == 0)
- return false;
-
- if (iv.size() != block_size_)
- return false;
-
- ok = CryptSetKeyParam(capi_key_.get(), KP_IV,
- reinterpret_cast<const BYTE*>(iv.data()), 0);
- if (!ok)
- return false;
-
- DWORD padding_method = PKCS5_PADDING;
- ok = CryptSetKeyParam(capi_key_.get(), KP_PADDING,
- reinterpret_cast<BYTE*>(&padding_method), 0);
- if (!ok)
- return false;
-
- return true;
-}
-
-bool Encryptor::Encrypt(const std::string& plaintext, std::string* ciphertext) {
- DWORD data_len = plaintext.size();
- DWORD total_len = data_len + block_size_;
-
- // CryptoAPI encrypts/decrypts in place.
- std::vector<BYTE> tmp(total_len);
- memcpy(&tmp[0], plaintext.data(), data_len);
-
- BOOL ok = CryptEncrypt(capi_key_.get(), NULL, TRUE, 0, &tmp[0],
- &data_len, total_len);
- if (!ok)
- return false;
-
- ciphertext->assign(reinterpret_cast<char*>(&tmp[0]), data_len);
- return true;
-}
-
-bool Encryptor::Decrypt(const std::string& ciphertext, std::string* plaintext) {
- DWORD data_len = ciphertext.size();
- if (data_len == 0)
- return false;
-
- std::vector<BYTE> tmp(data_len);
- memcpy(&tmp[0], ciphertext.data(), data_len);
-
- BOOL ok = CryptDecrypt(capi_key_.get(), NULL, TRUE, 0, &tmp[0], &data_len);
- if (!ok)
- return false;
-
- DCHECK_GT(tmp.size(), data_len);
-
- plaintext->assign(reinterpret_cast<char*>(&tmp[0]), data_len);
- return true;
-}
-
-} // namespace base
diff --git a/base/crypto/rsa_private_key.cc b/base/crypto/rsa_private_key.cc
deleted file mode 100644
index 024f741..0000000
--- a/base/crypto/rsa_private_key.cc
+++ /dev/null
@@ -1,390 +0,0 @@
-// Copyright (c) 2009 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.
-
-#include "base/crypto/rsa_private_key.h"
-
-#include <algorithm>
-#include <list>
-
-#include "base/logging.h"
-#include "base/scoped_ptr.h"
-#include "base/string_util.h"
-
-// This file manually encodes and decodes RSA private keys using PrivateKeyInfo
-// from PKCS #8 and RSAPrivateKey from PKCS #1. These structures are:
-//
-// PrivateKeyInfo ::= SEQUENCE {
-// version Version,
-// privateKeyAlgorithm PrivateKeyAlgorithmIdentifier,
-// privateKey PrivateKey,
-// attributes [0] IMPLICIT Attributes OPTIONAL
-// }
-//
-// RSAPrivateKey ::= SEQUENCE {
-// version Version,
-// modulus INTEGER,
-// publicExponent INTEGER,
-// privateExponent INTEGER,
-// prime1 INTEGER,
-// prime2 INTEGER,
-// exponent1 INTEGER,
-// exponent2 INTEGER,
-// coefficient INTEGER
-// }
-
-namespace {
-// Helper for error handling during key import.
-#define READ_ASSERT(truth) \
- if (!(truth)) { \
- NOTREACHED(); \
- return false; \
- }
-} // namespace
-
-namespace base {
-
-const uint8 PrivateKeyInfoCodec::kRsaAlgorithmIdentifier[] = {
- 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01,
- 0x05, 0x00
-};
-
-PrivateKeyInfoCodec::PrivateKeyInfoCodec(bool big_endian)
- : big_endian_(big_endian) {}
-
-PrivateKeyInfoCodec::~PrivateKeyInfoCodec() {}
-
-bool PrivateKeyInfoCodec::Export(std::vector<uint8>* output) {
- std::list<uint8> content;
-
- // Version (always zero)
- uint8 version = 0;
-
- PrependInteger(coefficient_, &content);
- PrependInteger(exponent2_, &content);
- PrependInteger(exponent1_, &content);
- PrependInteger(prime2_, &content);
- PrependInteger(prime1_, &content);
- PrependInteger(private_exponent_, &content);
- PrependInteger(public_exponent_, &content);
- PrependInteger(modulus_, &content);
- PrependInteger(&version, 1, &content);
- PrependTypeHeaderAndLength(kSequenceTag, content.size(), &content);
- PrependTypeHeaderAndLength(kOctetStringTag, content.size(), &content);
-
- // RSA algorithm OID
- for (size_t i = sizeof(kRsaAlgorithmIdentifier); i > 0; --i)
- content.push_front(kRsaAlgorithmIdentifier[i - 1]);
-
- PrependInteger(&version, 1, &content);
- PrependTypeHeaderAndLength(kSequenceTag, content.size(), &content);
-
- // Copy everying into the output.
- output->reserve(content.size());
- for (std::list<uint8>::iterator i = content.begin(); i != content.end(); ++i)
- output->push_back(*i);
-
- return true;
-}
-
-bool PrivateKeyInfoCodec::ExportPublicKeyInfo(std::vector<uint8>* output) {
- // Create a sequence with the modulus (n) and public exponent (e).
- std::vector<uint8> bit_string;
- if (!ExportPublicKey(&bit_string))
- return false;
-
- // Add the sequence as the contents of a bit string.
- std::list<uint8> content;
- PrependBitString(&bit_string[0], static_cast<int>(bit_string.size()),
- &content);
-
- // Add the RSA algorithm OID.
- for (size_t i = sizeof(kRsaAlgorithmIdentifier); i > 0; --i)
- content.push_front(kRsaAlgorithmIdentifier[i - 1]);
-
- // Finally, wrap everything in a sequence.
- PrependTypeHeaderAndLength(kSequenceTag, content.size(), &content);
-
- // Copy everything into the output.
- output->reserve(content.size());
- for (std::list<uint8>::iterator i = content.begin(); i != content.end(); ++i)
- output->push_back(*i);
-
- return true;
-}
-
-bool PrivateKeyInfoCodec::ExportPublicKey(std::vector<uint8>* output) {
- // Create a sequence with the modulus (n) and public exponent (e).
- std::list<uint8> content;
- PrependInteger(&public_exponent_[0],
- static_cast<int>(public_exponent_.size()),
- &content);
- PrependInteger(&modulus_[0], static_cast<int>(modulus_.size()), &content);
- PrependTypeHeaderAndLength(kSequenceTag, content.size(), &content);
-
- // Copy everything into the output.
- output->reserve(content.size());
- for (std::list<uint8>::iterator i = content.begin(); i != content.end(); ++i)
- output->push_back(*i);
-
- return true;
-}
-
-bool PrivateKeyInfoCodec::Import(const std::vector<uint8>& input) {
- if (input.empty()) {
- return false;
- }
-
- // Parse the private key info up to the public key values, ignoring
- // the subsequent private key values.
- uint8* src = const_cast<uint8*>(&input.front());
- uint8* end = src + input.size();
- if (!ReadSequence(&src, end) ||
- !ReadVersion(&src, end) ||
- !ReadAlgorithmIdentifier(&src, end) ||
- !ReadTypeHeaderAndLength(&src, end, kOctetStringTag, NULL) ||
- !ReadSequence(&src, end) ||
- !ReadVersion(&src, end) ||
- !ReadInteger(&src, end, &modulus_))
- return false;
-
- int mod_size = modulus_.size();
- READ_ASSERT(mod_size % 2 == 0);
- int primes_size = mod_size / 2;
-
- if (!ReadIntegerWithExpectedSize(&src, end, 4, &public_exponent_) ||
- !ReadIntegerWithExpectedSize(&src, end, mod_size, &private_exponent_) ||
- !ReadIntegerWithExpectedSize(&src, end, primes_size, &prime1_) ||
- !ReadIntegerWithExpectedSize(&src, end, primes_size, &prime2_) ||
- !ReadIntegerWithExpectedSize(&src, end, primes_size, &exponent1_) ||
- !ReadIntegerWithExpectedSize(&src, end, primes_size, &exponent2_) ||
- !ReadIntegerWithExpectedSize(&src, end, primes_size, &coefficient_))
- return false;
-
- READ_ASSERT(src == end);
-
-
- return true;
-}
-
-void PrivateKeyInfoCodec::PrependInteger(const std::vector<uint8>& in,
- std::list<uint8>* out) {
- uint8* ptr = const_cast<uint8*>(&in.front());
- PrependIntegerImpl(ptr, in.size(), out, big_endian_);
-}
-
-// Helper to prepend an ASN.1 integer.
-void PrivateKeyInfoCodec::PrependInteger(uint8* val,
- int num_bytes,
- std::list<uint8>* data) {
- PrependIntegerImpl(val, num_bytes, data, big_endian_);
-}
-
-void PrivateKeyInfoCodec::PrependIntegerImpl(uint8* val,
- int num_bytes,
- std::list<uint8>* data,
- bool big_endian) {
- // Reverse input if little-endian.
- std::vector<uint8> tmp;
- if (!big_endian) {
- tmp.assign(val, val + num_bytes);
- reverse(tmp.begin(), tmp.end());
- val = &tmp.front();
- }
-
- // ASN.1 integers are unpadded byte arrays, so skip any null padding bytes
- // from the most-significant end of the integer.
- int start = 0;
- while (start < (num_bytes - 1) && val[start] == 0x00) {
- start++;
- num_bytes--;
- }
- PrependBytes(val, start, num_bytes, data);
-
- // ASN.1 integers are signed. To encode a positive integer whose sign bit
- // (the most significant bit) would otherwise be set and make the number
- // negative, ASN.1 requires a leading null byte to force the integer to be
- // positive.
- uint8 front = data->front();
- if ((front & 0x80) != 0) {
- data->push_front(0x00);
- num_bytes++;
- }
-
- PrependTypeHeaderAndLength(kIntegerTag, num_bytes, data);
-}
-
-bool PrivateKeyInfoCodec::ReadInteger(uint8** pos,
- uint8* end,
- std::vector<uint8>* out) {
- return ReadIntegerImpl(pos, end, out, big_endian_);
-}
-
-bool PrivateKeyInfoCodec::ReadIntegerWithExpectedSize(uint8** pos,
- uint8* end,
- size_t expected_size,
- std::vector<uint8>* out) {
- std::vector<uint8> temp;
- if (!ReadIntegerImpl(pos, end, &temp, true)) // Big-Endian
- return false;
-
- int pad = expected_size - temp.size();
- int index = 0;
- if (out->size() == expected_size + 1) {
- READ_ASSERT(out->front() == 0x00);
- pad++;
- index++;
- } else {
- READ_ASSERT(out->size() <= expected_size);
- }
-
- while (pad) {
- out->push_back(0x00);
- pad--;
- }
- out->insert(out->end(), temp.begin(), temp.end());
-
- // Reverse output if little-endian.
- if (!big_endian_)
- reverse(out->begin(), out->end());
- return true;
-}
-
-bool PrivateKeyInfoCodec::ReadIntegerImpl(uint8** pos,
- uint8* end,
- std::vector<uint8>* out,
- bool big_endian) {
- uint32 length = 0;
- if (!ReadTypeHeaderAndLength(pos, end, kIntegerTag, &length) || !length)
- return false;
-
- // The first byte can be zero to force positiveness. We can ignore this.
- if (**pos == 0x00) {
- ++(*pos);
- --length;
- }
-
- if (length)
- out->insert(out->end(), *pos, (*pos) + length);
-
- (*pos) += length;
-
- // Reverse output if little-endian.
- if (!big_endian)
- reverse(out->begin(), out->end());
- return true;
-}
-
-void PrivateKeyInfoCodec::PrependBytes(uint8* val,
- int start,
- int num_bytes,
- std::list<uint8>* data) {
- while (num_bytes > 0) {
- --num_bytes;
- data->push_front(val[start + num_bytes]);
- }
-}
-
-void PrivateKeyInfoCodec::PrependLength(size_t size, std::list<uint8>* data) {
- // The high bit is used to indicate whether additional octets are needed to
- // represent the length.
- if (size < 0x80) {
- data->push_front(static_cast<uint8>(size));
- } else {
- uint8 num_bytes = 0;
- while (size > 0) {
- data->push_front(static_cast<uint8>(size & 0xFF));
- size >>= 8;
- num_bytes++;
- }
- CHECK_LE(num_bytes, 4);
- data->push_front(0x80 | num_bytes);
- }
-}
-
-void PrivateKeyInfoCodec::PrependTypeHeaderAndLength(uint8 type,
- uint32 length,
- std::list<uint8>* output) {
- PrependLength(length, output);
- output->push_front(type);
-}
-
-void PrivateKeyInfoCodec::PrependBitString(uint8* val,
- int num_bytes,
- std::list<uint8>* output) {
- // Start with the data.
- PrependBytes(val, 0, num_bytes, output);
- // Zero unused bits.
- output->push_front(0);
- // Add the length.
- PrependLength(num_bytes + 1, output);
- // Finally, add the bit string tag.
- output->push_front((uint8) kBitStringTag);
-}
-
-bool PrivateKeyInfoCodec::ReadLength(uint8** pos, uint8* end, uint32* result) {
- READ_ASSERT(*pos < end);
- int length = 0;
-
- // If the MSB is not set, the length is just the byte itself.
- if (!(**pos & 0x80)) {
- length = **pos;
- (*pos)++;
- } else {
- // Otherwise, the lower 7 indicate the length of the length.
- int length_of_length = **pos & 0x7F;
- READ_ASSERT(length_of_length <= 4);
- (*pos)++;
- READ_ASSERT(*pos + length_of_length < end);
-
- length = 0;
- for (int i = 0; i < length_of_length; ++i) {
- length <<= 8;
- length |= **pos;
- (*pos)++;
- }
- }
-
- READ_ASSERT(*pos + length <= end);
- if (result) *result = length;
- return true;
-}
-
-bool PrivateKeyInfoCodec::ReadTypeHeaderAndLength(uint8** pos,
- uint8* end,
- uint8 expected_tag,
- uint32* length) {
- READ_ASSERT(*pos < end);
- READ_ASSERT(**pos == expected_tag);
- (*pos)++;
-
- return ReadLength(pos, end, length);
-}
-
-bool PrivateKeyInfoCodec::ReadSequence(uint8** pos, uint8* end) {
- return ReadTypeHeaderAndLength(pos, end, kSequenceTag, NULL);
-}
-
-bool PrivateKeyInfoCodec::ReadAlgorithmIdentifier(uint8** pos, uint8* end) {
- READ_ASSERT(*pos + sizeof(kRsaAlgorithmIdentifier) < end);
- READ_ASSERT(memcmp(*pos, kRsaAlgorithmIdentifier,
- sizeof(kRsaAlgorithmIdentifier)) == 0);
- (*pos) += sizeof(kRsaAlgorithmIdentifier);
- return true;
-}
-
-bool PrivateKeyInfoCodec::ReadVersion(uint8** pos, uint8* end) {
- uint32 length = 0;
- if (!ReadTypeHeaderAndLength(pos, end, kIntegerTag, &length))
- return false;
-
- // The version should be zero.
- for (uint32 i = 0; i < length; ++i) {
- READ_ASSERT(**pos == 0x00);
- (*pos)++;
- }
-
- return true;
-}
-
-} // namespace base
diff --git a/base/crypto/rsa_private_key.h b/base/crypto/rsa_private_key.h
deleted file mode 100644
index 5357adc..0000000
--- a/base/crypto/rsa_private_key.h
+++ /dev/null
@@ -1,273 +0,0 @@
-// Copyright (c) 2011 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 BASE_CRYPTO_RSA_PRIVATE_KEY_H_
-#define BASE_CRYPTO_RSA_PRIVATE_KEY_H_
-#pragma once
-
-#include "build/build_config.h"
-
-#if defined(USE_OPENSSL)
-// Forward declaration for openssl/*.h
-typedef struct evp_pkey_st EVP_PKEY;
-#elif defined(USE_NSS)
-// Forward declaration.
-struct SECKEYPrivateKeyStr;
-struct SECKEYPublicKeyStr;
-#elif defined(OS_MACOSX)
-#include <Security/cssm.h>
-#endif
-
-#include <list>
-#include <vector>
-
-#include "base/basictypes.h"
-
-#if defined(OS_WIN)
-#include "base/crypto/scoped_capi_types.h"
-#endif
-#if defined(USE_NSS)
-#include "base/gtest_prod_util.h"
-#endif
-
-namespace base {
-
-// Used internally by RSAPrivateKey for serializing and deserializing
-// PKCS #8 PrivateKeyInfo and PublicKeyInfo.
-class PrivateKeyInfoCodec {
- public:
-
- // ASN.1 encoding of the AlgorithmIdentifier from PKCS #8.
- static const uint8 kRsaAlgorithmIdentifier[];
-
- // ASN.1 tags for some types we use.
- static const uint8 kBitStringTag = 0x03;
- static const uint8 kIntegerTag = 0x02;
- static const uint8 kNullTag = 0x05;
- static const uint8 kOctetStringTag = 0x04;
- static const uint8 kSequenceTag = 0x30;
-
- // |big_endian| here specifies the byte-significance of the integer components
- // that will be parsed & serialized (modulus(), etc...) during Import(),
- // Export() and ExportPublicKeyInfo() -- not the ASN.1 DER encoding of the
- // PrivateKeyInfo/PublicKeyInfo (which is always big-endian).
- explicit PrivateKeyInfoCodec(bool big_endian);
-
- ~PrivateKeyInfoCodec();
-
- // Exports the contents of the integer components to the ASN.1 DER encoding
- // of the PrivateKeyInfo structure to |output|.
- bool Export(std::vector<uint8>* output);
-
- // Exports the contents of the integer components to the ASN.1 DER encoding
- // of the PublicKeyInfo structure to |output|.
- bool ExportPublicKeyInfo(std::vector<uint8>* output);
-
- // Exports the contents of the integer components to the ASN.1 DER encoding
- // of the RSAPublicKey structure to |output|.
- bool ExportPublicKey(std::vector<uint8>* output);
-
- // Parses the ASN.1 DER encoding of the PrivateKeyInfo structure in |input|
- // and populates the integer components with |big_endian_| byte-significance.
- // IMPORTANT NOTE: This is currently *not* security-approved for importing
- // keys from unstrusted sources.
- bool Import(const std::vector<uint8>& input);
-
- // Accessors to the contents of the integer components of the PrivateKeyInfo
- // structure.
- std::vector<uint8>* modulus() { return &modulus_; };
- std::vector<uint8>* public_exponent() { return &public_exponent_; };
- std::vector<uint8>* private_exponent() { return &private_exponent_; };
- std::vector<uint8>* prime1() { return &prime1_; };
- std::vector<uint8>* prime2() { return &prime2_; };
- std::vector<uint8>* exponent1() { return &exponent1_; };
- std::vector<uint8>* exponent2() { return &exponent2_; };
- std::vector<uint8>* coefficient() { return &coefficient_; };
-
- private:
- // Utility wrappers for PrependIntegerImpl that use the class's |big_endian_|
- // value.
- void PrependInteger(const std::vector<uint8>& in, std::list<uint8>* out);
- void PrependInteger(uint8* val, int num_bytes, std::list<uint8>* data);
-
- // Prepends the integer stored in |val| - |val + num_bytes| with |big_endian|
- // byte-significance into |data| as an ASN.1 integer.
- void PrependIntegerImpl(uint8* val,
- int num_bytes,
- std::list<uint8>* data,
- bool big_endian);
-
- // Utility wrappers for ReadIntegerImpl that use the class's |big_endian_|
- // value.
- bool ReadInteger(uint8** pos, uint8* end, std::vector<uint8>* out);
- bool ReadIntegerWithExpectedSize(uint8** pos,
- uint8* end,
- size_t expected_size,
- std::vector<uint8>* out);
-
- // Reads an ASN.1 integer from |pos|, and stores the result into |out| with
- // |big_endian| byte-significance.
- bool ReadIntegerImpl(uint8** pos,
- uint8* end,
- std::vector<uint8>* out,
- bool big_endian);
-
- // Prepends the integer stored in |val|, starting a index |start|, for
- // |num_bytes| bytes onto |data|.
- void PrependBytes(uint8* val,
- int start,
- int num_bytes,
- std::list<uint8>* data);
-
- // Helper to prepend an ASN.1 length field.
- void PrependLength(size_t size, std::list<uint8>* data);
-
- // Helper to prepend an ASN.1 type header.
- void PrependTypeHeaderAndLength(uint8 type,
- uint32 length,
- std::list<uint8>* output);
-
- // Helper to prepend an ASN.1 bit string
- void PrependBitString(uint8* val, int num_bytes, std::list<uint8>* output);
-
- // Read an ASN.1 length field. This also checks that the length does not
- // extend beyond |end|.
- bool ReadLength(uint8** pos, uint8* end, uint32* result);
-
- // Read an ASN.1 type header and its length.
- bool ReadTypeHeaderAndLength(uint8** pos,
- uint8* end,
- uint8 expected_tag,
- uint32* length);
-
- // Read an ASN.1 sequence declaration. This consumes the type header and
- // length field, but not the contents of the sequence.
- bool ReadSequence(uint8** pos, uint8* end);
-
- // Read the RSA AlgorithmIdentifier.
- bool ReadAlgorithmIdentifier(uint8** pos, uint8* end);
-
- // Read one of the two version fields in PrivateKeyInfo.
- bool ReadVersion(uint8** pos, uint8* end);
-
- // The byte-significance of the stored components (modulus, etc..).
- bool big_endian_;
-
- // Component integers of the PrivateKeyInfo
- std::vector<uint8> modulus_;
- std::vector<uint8> public_exponent_;
- std::vector<uint8> private_exponent_;
- std::vector<uint8> prime1_;
- std::vector<uint8> prime2_;
- std::vector<uint8> exponent1_;
- std::vector<uint8> exponent2_;
- std::vector<uint8> coefficient_;
-
- DISALLOW_COPY_AND_ASSIGN(PrivateKeyInfoCodec);
-};
-
-// Encapsulates an RSA private key. Can be used to generate new keys, export
-// keys to other formats, or to extract a public key.
-// TODO(hclam): This class should be ref-counted so it can be reused easily.
-class RSAPrivateKey {
- public:
- ~RSAPrivateKey();
-
- // Create a new random instance. Can return NULL if initialization fails.
- static RSAPrivateKey* Create(uint16 num_bits);
-
- // Create a new random instance. Can return NULL if initialization fails.
- // The created key is permanent and is not exportable in plaintext form.
- //
- // NOTE: Currently only available if USE_NSS is defined.
- static RSAPrivateKey* CreateSensitive(uint16 num_bits);
-
- // Create a new instance by importing an existing private key. The format is
- // an ASN.1-encoded PrivateKeyInfo block from PKCS #8. This can return NULL if
- // initialization fails.
- static RSAPrivateKey* CreateFromPrivateKeyInfo(
- const std::vector<uint8>& input);
-
- // Create a new instance by importing an existing private key. The format is
- // an ASN.1-encoded PrivateKeyInfo block from PKCS #8. This can return NULL if
- // initialization fails.
- // The created key is permanent and is not exportable in plaintext form.
- //
- // NOTE: Currently only available if USE_NSS is defined.
- static RSAPrivateKey* CreateSensitiveFromPrivateKeyInfo(
- const std::vector<uint8>& input);
-
- // Import an existing public key, and then search for the private
- // half in the key database. The format of the public key blob is is
- // an X509 SubjectPublicKeyInfo block. This can return NULL if
- // initialization fails or the private key cannot be found. The
- // caller takes ownership of the returned object, but nothing new is
- // created in the key database.
- //
- // NOTE: Currently only available if USE_NSS is defined.
- static RSAPrivateKey* FindFromPublicKeyInfo(
- const std::vector<uint8>& input);
-
-#if defined(USE_OPENSSL)
- EVP_PKEY* key() { return key_; }
-#elif defined(USE_NSS)
- SECKEYPrivateKeyStr* key() { return key_; }
- SECKEYPublicKeyStr* public_key() { return public_key_; }
-#elif defined(OS_WIN)
- HCRYPTPROV provider() { return provider_; }
- HCRYPTKEY key() { return key_; }
-#elif defined(OS_MACOSX)
- CSSM_KEY_PTR key() { return &key_; }
- CSSM_KEY_PTR public_key() { return &public_key_; }
-#endif
-
- // Exports the private key to a PKCS #1 PrivateKey block.
- bool ExportPrivateKey(std::vector<uint8>* output);
-
- // Exports the public key to an X509 SubjectPublicKeyInfo block.
- bool ExportPublicKey(std::vector<uint8>* output);
-
- private:
-#if defined(USE_NSS)
- FRIEND_TEST_ALL_PREFIXES(RSAPrivateKeyNSSTest, FindFromPublicKey);
- FRIEND_TEST_ALL_PREFIXES(RSAPrivateKeyNSSTest, FailedFindFromPublicKey);
-#endif
-
- // Constructor is private. Use one of the Create*() or Find*()
- // methods above instead.
- RSAPrivateKey();
-
- // Shared helper for Create() and CreateSensitive().
- // TODO(cmasone): consider replacing |permanent| and |sensitive| with a
- // flags arg created by ORing together some enumerated values.
- static RSAPrivateKey* CreateWithParams(uint16 num_bits,
- bool permanent,
- bool sensitive);
-
- // Shared helper for CreateFromPrivateKeyInfo() and
- // CreateSensitiveFromPrivateKeyInfo().
- static RSAPrivateKey* CreateFromPrivateKeyInfoWithParams(
- const std::vector<uint8>& input, bool permanent, bool sensitive);
-
-#if defined(USE_OPENSSL)
- EVP_PKEY* key_;
-#elif defined(USE_NSS)
- SECKEYPrivateKeyStr* key_;
- SECKEYPublicKeyStr* public_key_;
-#elif defined(OS_WIN)
- bool InitProvider();
-
- ScopedHCRYPTPROV provider_;
- ScopedHCRYPTKEY key_;
-#elif defined(OS_MACOSX)
- CSSM_KEY key_;
- CSSM_KEY public_key_;
-#endif
-
- DISALLOW_COPY_AND_ASSIGN(RSAPrivateKey);
-};
-
-} // namespace base
-
-#endif // BASE_CRYPTO_RSA_PRIVATE_KEY_H_
diff --git a/base/crypto/rsa_private_key_mac.cc b/base/crypto/rsa_private_key_mac.cc
deleted file mode 100644
index ede8014..0000000
--- a/base/crypto/rsa_private_key_mac.cc
+++ /dev/null
@@ -1,196 +0,0 @@
-// Copyright (c) 2009 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.
-
-#include "base/crypto/rsa_private_key.h"
-
-#include <list>
-
-#include "base/crypto/cssm_init.h"
-#include "base/logging.h"
-#include "base/scoped_ptr.h"
-
-namespace base {
-
-// static
-RSAPrivateKey* RSAPrivateKey::Create(uint16 num_bits) {
- scoped_ptr<RSAPrivateKey> result(new RSAPrivateKey);
-
- CSSM_CC_HANDLE cc_handle;
- CSSM_RETURN crtn;
- crtn = CSSM_CSP_CreateKeyGenContext(GetSharedCSPHandle(), CSSM_ALGID_RSA,
- num_bits, NULL, NULL, NULL, NULL, NULL,
- &cc_handle);
- if (crtn) {
- NOTREACHED() << "CSSM_CSP_CreateKeyGenContext failed: " << crtn;
- return NULL;
- }
-
- CSSM_DATA label = { 9,
- const_cast<uint8*>(reinterpret_cast<const uint8*>("temp_key")) };
- crtn = CSSM_GenerateKeyPair(cc_handle,
- CSSM_KEYUSE_VERIFY,
- CSSM_KEYATTR_RETURN_DATA | CSSM_KEYATTR_EXTRACTABLE, &label,
- result->public_key(), CSSM_KEYUSE_SIGN,
- CSSM_KEYATTR_RETURN_DATA | CSSM_KEYATTR_EXTRACTABLE, &label, NULL,
- result->key());
- CSSM_DeleteContext(cc_handle);
- if (crtn) {
- NOTREACHED() << "CSSM_CSP_CreateKeyGenContext failed: " << crtn;
- return NULL;
- }
-
- return result.release();
-}
-
-// static
-RSAPrivateKey* RSAPrivateKey::CreateSensitive(uint16 num_bits) {
- NOTIMPLEMENTED();
- return NULL;
-}
-
-// static
-RSAPrivateKey* RSAPrivateKey::CreateFromPrivateKeyInfo(
- const std::vector<uint8>& input) {
- if (input.empty())
- return NULL;
-
- scoped_ptr<RSAPrivateKey> result(new RSAPrivateKey);
-
- CSSM_KEY key;
- memset(&key, 0, sizeof(key));
- key.KeyData.Data = const_cast<uint8*>(&input.front());
- key.KeyData.Length = input.size();
- key.KeyHeader.Format = CSSM_KEYBLOB_RAW_FORMAT_PKCS8;
- key.KeyHeader.HeaderVersion = CSSM_KEYHEADER_VERSION;
- key.KeyHeader.BlobType = CSSM_KEYBLOB_RAW;
- key.KeyHeader.AlgorithmId = CSSM_ALGID_RSA;
- key.KeyHeader.KeyClass = CSSM_KEYCLASS_PRIVATE_KEY;
- key.KeyHeader.KeyAttr = CSSM_KEYATTR_EXTRACTABLE;
- key.KeyHeader.KeyUsage = CSSM_KEYUSE_ANY;
-
- CSSM_KEY_SIZE key_size;
- CSSM_RETURN crtn;
- crtn = CSSM_QueryKeySizeInBits(GetSharedCSPHandle(), NULL, &key, &key_size);
- if (crtn) {
- NOTREACHED() << "CSSM_QueryKeySizeInBits failed: " << crtn;
- return NULL;
- }
- key.KeyHeader.LogicalKeySizeInBits = key_size.LogicalKeySizeInBits;
-
- // Perform a NULL unwrap operation on the key so that result's key_
- // instance variable points to a key that can be released via CSSM_FreeKey().
- CSSM_ACCESS_CREDENTIALS creds;
- memset(&creds, 0, sizeof(CSSM_ACCESS_CREDENTIALS));
- CSSM_CC_HANDLE cc_handle;
- crtn = CSSM_CSP_CreateSymmetricContext(GetSharedCSPHandle(), CSSM_ALGID_NONE,
- CSSM_ALGMODE_NONE, &creds, NULL, NULL, CSSM_PADDING_NONE, 0, &cc_handle);
- if (crtn) {
- NOTREACHED() << "CSSM_CSP_CreateSymmetricContext failed: " << crtn;
- return NULL;
- }
- CSSM_DATA label_data, desc_data = { 0, NULL };
- label_data.Data =
- const_cast<uint8*>(reinterpret_cast<const uint8*>("unwrapped"));
- label_data.Length = 9;
- crtn = CSSM_UnwrapKey(cc_handle, NULL, &key, CSSM_KEYUSE_ANY,
- CSSM_KEYATTR_RETURN_DATA | CSSM_KEYATTR_EXTRACTABLE, &label_data,
- NULL, result->key(), &desc_data);
- if (crtn) {
- NOTREACHED() << "CSSM_UnwrapKey failed: " << crtn;
- return NULL;
- }
-
- // Extract a public key from the private key.
- // Apple doesn't accept CSSM_KEYBLOB_RAW_FORMAT_X509 as a valid key
- // format when attempting to generate certs, so use PKCS1 instead.
- PrivateKeyInfoCodec codec(true);
- std::vector<uint8> private_key_data;
- private_key_data.assign(key.KeyData.Data,
- key.KeyData.Data + key.KeyData.Length);
- if (!codec.Import(private_key_data)) {
- return NULL;
- }
- std::vector<uint8> public_key_data;
- if (!codec.ExportPublicKey(&public_key_data)) {
- return NULL;
- }
-
- CSSM_KEY* public_key = result->public_key();
- size_t size = public_key_data.size();
- public_key->KeyData.Data = reinterpret_cast<uint8*>(CSSMMalloc(size));
- if (!public_key->KeyData.Data) {
- NOTREACHED() << "CSSMMalloc failed";
- return NULL;
- }
- memcpy(public_key->KeyData.Data, &public_key_data.front(), size);
- public_key->KeyData.Length = size;
- public_key->KeyHeader.Format = CSSM_KEYBLOB_RAW_FORMAT_PKCS1;
- public_key->KeyHeader.HeaderVersion = CSSM_KEYHEADER_VERSION;
- public_key->KeyHeader.BlobType = CSSM_KEYBLOB_RAW;
- public_key->KeyHeader.AlgorithmId = CSSM_ALGID_RSA;
- public_key->KeyHeader.KeyClass = CSSM_KEYCLASS_PUBLIC_KEY;
- public_key->KeyHeader.KeyAttr = CSSM_KEYATTR_EXTRACTABLE;
- public_key->KeyHeader.KeyUsage = CSSM_KEYUSE_ANY;
-
- crtn = CSSM_QueryKeySizeInBits(
- base::GetSharedCSPHandle(), NULL, public_key, &key_size);
- if (crtn) {
- DLOG(ERROR) << "CSSM_QueryKeySizeInBits failed " << crtn;
- return NULL;
- }
- public_key->KeyHeader.LogicalKeySizeInBits = key_size.LogicalKeySizeInBits;
-
- return result.release();
-}
-
-// static
-RSAPrivateKey* RSAPrivateKey::CreateSensitiveFromPrivateKeyInfo(
- const std::vector<uint8>& input) {
- NOTIMPLEMENTED();
- return NULL;
-}
-
-// static
-RSAPrivateKey* RSAPrivateKey::FindFromPublicKeyInfo(
- const std::vector<uint8>& input) {
- NOTIMPLEMENTED();
- return NULL;
-}
-
-RSAPrivateKey::RSAPrivateKey() {
- memset(&key_, 0, sizeof(key_));
- memset(&public_key_, 0, sizeof(public_key_));
-
- EnsureCSSMInit();
-}
-
-RSAPrivateKey::~RSAPrivateKey() {
- if (key_.KeyData.Data) {
- CSSM_FreeKey(GetSharedCSPHandle(), NULL, &key_, CSSM_FALSE);
- }
- if (public_key_.KeyData.Data) {
- CSSM_FreeKey(GetSharedCSPHandle(), NULL, &public_key_, CSSM_FALSE);
- }
-}
-
-bool RSAPrivateKey::ExportPrivateKey(std::vector<uint8>* output) {
- if (!key_.KeyData.Data || !key_.KeyData.Length) {
- return false;
- }
- output->clear();
- output->insert(output->end(), key_.KeyData.Data,
- key_.KeyData.Data + key_.KeyData.Length);
- return true;
-}
-
-bool RSAPrivateKey::ExportPublicKey(std::vector<uint8>* output) {
- PrivateKeyInfoCodec private_key_info(true);
- std::vector<uint8> private_key_data;
- private_key_data.assign(key_.KeyData.Data,
- key_.KeyData.Data + key_.KeyData.Length);
- return (private_key_info.Import(private_key_data) &&
- private_key_info.ExportPublicKeyInfo(output));
-}
-
-} // namespace base
diff --git a/base/crypto/rsa_private_key_nss.cc b/base/crypto/rsa_private_key_nss.cc
deleted file mode 100644
index 202aa1d..0000000
--- a/base/crypto/rsa_private_key_nss.cc
+++ /dev/null
@@ -1,248 +0,0 @@
-// Copyright (c) 2009 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.
-
-#include "base/crypto/rsa_private_key.h"
-
-#include <cryptohi.h>
-#include <keyhi.h>
-#include <pk11pub.h>
-
-#include <list>
-
-#include "base/debug/leak_annotations.h"
-#include "base/logging.h"
-#include "base/nss_util.h"
-#include "base/nss_util_internal.h"
-#include "base/scoped_ptr.h"
-#include "base/string_util.h"
-
-// TODO(rafaelw): Consider refactoring common functions and definitions from
-// rsa_private_key_win.cc or using NSS's ASN.1 encoder.
-namespace {
-
-static bool ReadAttribute(SECKEYPrivateKey* key,
- CK_ATTRIBUTE_TYPE type,
- std::vector<uint8>* output) {
- SECItem item;
- SECStatus rv;
- rv = PK11_ReadRawAttribute(PK11_TypePrivKey, key, type, &item);
- if (rv != SECSuccess) {
- NOTREACHED();
- return false;
- }
-
- output->assign(item.data, item.data + item.len);
- SECITEM_FreeItem(&item, PR_FALSE);
- return true;
-}
-
-} // namespace
-
-namespace base {
-
-RSAPrivateKey::~RSAPrivateKey() {
- if (key_)
- SECKEY_DestroyPrivateKey(key_);
- if (public_key_)
- SECKEY_DestroyPublicKey(public_key_);
-}
-
-// static
-RSAPrivateKey* RSAPrivateKey::Create(uint16 num_bits) {
- return CreateWithParams(num_bits,
- PR_FALSE /* not permanent */,
- PR_FALSE /* not sensitive */);
-}
-
-// static
-RSAPrivateKey* RSAPrivateKey::CreateSensitive(uint16 num_bits) {
- return CreateWithParams(num_bits,
- PR_TRUE /* permanent */,
- PR_TRUE /* sensitive */);
-}
-
-// static
-RSAPrivateKey* RSAPrivateKey::CreateFromPrivateKeyInfo(
- const std::vector<uint8>& input) {
- return CreateFromPrivateKeyInfoWithParams(input,
- PR_FALSE /* not permanent */,
- PR_FALSE /* not sensitive */);
-}
-
-// static
-RSAPrivateKey* RSAPrivateKey::CreateSensitiveFromPrivateKeyInfo(
- const std::vector<uint8>& input) {
- return CreateFromPrivateKeyInfoWithParams(input,
- PR_TRUE /* permanent */,
- PR_TRUE /* seneitive */);
-}
-
-// static
-RSAPrivateKey* RSAPrivateKey::FindFromPublicKeyInfo(
- const std::vector<uint8>& input) {
- base::EnsureNSSInit();
-
- scoped_ptr<RSAPrivateKey> result(new RSAPrivateKey);
-
- // First, decode and save the public key.
- SECItem key_der;
- key_der.type = siBuffer;
- key_der.data = const_cast<unsigned char*>(&input[0]);
- key_der.len = input.size();
-
- CERTSubjectPublicKeyInfo *spki =
- SECKEY_DecodeDERSubjectPublicKeyInfo(&key_der);
- if (!spki) {
- NOTREACHED();
- return NULL;
- }
-
- result->public_key_ = SECKEY_ExtractPublicKey(spki);
- SECKEY_DestroySubjectPublicKeyInfo(spki);
- if (!result->public_key_) {
- NOTREACHED();
- return NULL;
- }
-
- // Now, look for the associated private key in the user's NSS DB. If it's
- // not there, consider that an error.
- PK11SlotInfo *slot = GetDefaultNSSKeySlot();
- if (!slot) {
- NOTREACHED();
- return NULL;
- }
-
- // Make sure the key is an RSA key. If not, that's an error
- if (result->public_key_->keyType != rsaKey) {
- PK11_FreeSlot(slot);
- NOTREACHED();
- return NULL;
- }
-
- SECItem *ck_id = PK11_MakeIDFromPubKey(&(result->public_key_->u.rsa.modulus));
- if (!ck_id) {
- PK11_FreeSlot(slot);
- NOTREACHED();
- return NULL;
- }
-
- // Finally...Look for the key!
- result->key_ = PK11_FindKeyByKeyID(slot, ck_id, NULL);
-
- // Cleanup...
- PK11_FreeSlot(slot);
- SECITEM_FreeItem(ck_id, PR_TRUE);
-
- // If we didn't find it, that's ok.
- if (!result->key_)
- return NULL;
-
- return result.release();
-}
-
-
-bool RSAPrivateKey::ExportPrivateKey(std::vector<uint8>* output) {
- PrivateKeyInfoCodec private_key_info(true);
-
- // Manually read the component attributes of the private key and build up
- // the PrivateKeyInfo.
- if (!ReadAttribute(key_, CKA_MODULUS, private_key_info.modulus()) ||
- !ReadAttribute(key_, CKA_PUBLIC_EXPONENT,
- private_key_info.public_exponent()) ||
- !ReadAttribute(key_, CKA_PRIVATE_EXPONENT,
- private_key_info.private_exponent()) ||
- !ReadAttribute(key_, CKA_PRIME_1, private_key_info.prime1()) ||
- !ReadAttribute(key_, CKA_PRIME_2, private_key_info.prime2()) ||
- !ReadAttribute(key_, CKA_EXPONENT_1, private_key_info.exponent1()) ||
- !ReadAttribute(key_, CKA_EXPONENT_2, private_key_info.exponent2()) ||
- !ReadAttribute(key_, CKA_COEFFICIENT, private_key_info.coefficient())) {
- NOTREACHED();
- return false;
- }
-
- return private_key_info.Export(output);
-}
-
-bool RSAPrivateKey::ExportPublicKey(std::vector<uint8>* output) {
- SECItem* der_pubkey = SECKEY_EncodeDERSubjectPublicKeyInfo(public_key_);
- if (!der_pubkey) {
- NOTREACHED();
- return false;
- }
-
- for (size_t i = 0; i < der_pubkey->len; ++i)
- output->push_back(der_pubkey->data[i]);
-
- SECITEM_FreeItem(der_pubkey, PR_TRUE);
- return true;
-}
-
-RSAPrivateKey::RSAPrivateKey() : key_(NULL), public_key_(NULL) {
- EnsureNSSInit();
-}
-
-// static
-RSAPrivateKey* RSAPrivateKey::CreateWithParams(uint16 num_bits,
- bool permanent,
- bool sensitive) {
- base::EnsureNSSInit();
-
- scoped_ptr<RSAPrivateKey> result(new RSAPrivateKey);
-
- PK11SlotInfo *slot = GetDefaultNSSKeySlot();
- if (!slot)
- return NULL;
-
- PK11RSAGenParams param;
- param.keySizeInBits = num_bits;
- param.pe = 65537L;
- result->key_ = PK11_GenerateKeyPair(slot, CKM_RSA_PKCS_KEY_PAIR_GEN, &param,
- &result->public_key_, permanent, sensitive, NULL);
- PK11_FreeSlot(slot);
- if (!result->key_)
- return NULL;
-
- return result.release();
-}
-
-// static
-RSAPrivateKey* RSAPrivateKey::CreateFromPrivateKeyInfoWithParams(
- const std::vector<uint8>& input, bool permanent, bool sensitive) {
- // This method currently leaks some memory.
- // See http://crbug.com/34742.
- ANNOTATE_SCOPED_MEMORY_LEAK;
- base::EnsureNSSInit();
-
- scoped_ptr<RSAPrivateKey> result(new RSAPrivateKey);
-
- PK11SlotInfo *slot = GetDefaultNSSKeySlot();
- if (!slot)
- return NULL;
-
- SECItem der_private_key_info;
- der_private_key_info.data = const_cast<unsigned char*>(&input.front());
- der_private_key_info.len = input.size();
- // Allow the private key to be used for key unwrapping, data decryption,
- // and signature generation.
- const unsigned int key_usage = KU_KEY_ENCIPHERMENT | KU_DATA_ENCIPHERMENT |
- KU_DIGITAL_SIGNATURE;
- SECStatus rv = PK11_ImportDERPrivateKeyInfoAndReturnKey(
- slot, &der_private_key_info, NULL, NULL, permanent, sensitive,
- key_usage, &result->key_, NULL);
- PK11_FreeSlot(slot);
- if (rv != SECSuccess) {
- NOTREACHED();
- return NULL;
- }
-
- result->public_key_ = SECKEY_ConvertToPublicKey(result->key_);
- if (!result->public_key_) {
- NOTREACHED();
- return NULL;
- }
-
- return result.release();
-}
-
-} // namespace base
diff --git a/base/crypto/rsa_private_key_nss_unittest.cc b/base/crypto/rsa_private_key_nss_unittest.cc
deleted file mode 100644
index 7dbe628..0000000
--- a/base/crypto/rsa_private_key_nss_unittest.cc
+++ /dev/null
@@ -1,64 +0,0 @@
-// 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.
-
-#include "base/crypto/rsa_private_key.h"
-
-#include <keyhi.h>
-#include <pk11pub.h>
-
-#include "base/nss_util.h"
-#include "base/scoped_ptr.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace base {
-
-class RSAPrivateKeyNSSTest : public testing::Test {
- public:
- RSAPrivateKeyNSSTest() {}
- virtual ~RSAPrivateKeyNSSTest() {}
-
- virtual void SetUp() {
-#if defined(OS_CHROMEOS)
- base::OpenPersistentNSSDB();
-#endif
- }
-
- private:
- DISALLOW_COPY_AND_ASSIGN(RSAPrivateKeyNSSTest);
-};
-
-TEST_F(RSAPrivateKeyNSSTest, FindFromPublicKey) {
- // Create a keypair, which will put the keys in the user's NSSDB.
- scoped_ptr<base::RSAPrivateKey> key_pair(base::RSAPrivateKey::Create(256));
-
- std::vector<uint8> public_key;
- ASSERT_TRUE(key_pair->ExportPublicKey(&public_key));
-
- scoped_ptr<base::RSAPrivateKey> key_pair_2(
- base::RSAPrivateKey::FindFromPublicKeyInfo(public_key));
-
- EXPECT_EQ(key_pair->key_->pkcs11ID, key_pair_2->key_->pkcs11ID);
-}
-
-TEST_F(RSAPrivateKeyNSSTest, FailedFindFromPublicKey) {
- // Create a keypair, which will put the keys in the user's NSSDB.
- scoped_ptr<base::RSAPrivateKey> key_pair(base::RSAPrivateKey::Create(256));
-
- std::vector<uint8> public_key;
- ASSERT_TRUE(key_pair->ExportPublicKey(&public_key));
-
- // Remove the keys from the DB, and make sure we can't find them again.
- if (key_pair->key_) {
- PK11_DestroyTokenObject(key_pair->key_->pkcs11Slot,
- key_pair->key_->pkcs11ID);
- }
- if (key_pair->public_key_) {
- PK11_DestroyTokenObject(key_pair->public_key_->pkcs11Slot,
- key_pair->public_key_->pkcs11ID);
- }
-
- EXPECT_EQ(NULL, base::RSAPrivateKey::FindFromPublicKeyInfo(public_key));
-}
-
-} // namespace base
diff --git a/base/crypto/rsa_private_key_openssl.cc b/base/crypto/rsa_private_key_openssl.cc
deleted file mode 100644
index 891ea52..0000000
--- a/base/crypto/rsa_private_key_openssl.cc
+++ /dev/null
@@ -1,135 +0,0 @@
-// 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.
-
-#include "base/crypto/rsa_private_key.h"
-
-#include <openssl/evp.h>
-#include <openssl/pkcs12.h>
-#include <openssl/rsa.h>
-
-#include "base/logging.h"
-#include "base/openssl_util.h"
-#include "base/scoped_ptr.h"
-#include "base/stl_util-inl.h"
-
-namespace base {
-
-namespace {
-
-// Function pointer definition, for injecting the required key export function
-// into ExportKey, below. The supplied function should export EVP_PKEY into
-// the supplied BIO, returning 1 on success or 0 on failure.
-typedef int (ExportFunction)(BIO*, EVP_PKEY*);
-
-// Helper to export |key| into |output| via the specified ExportFunction.
-bool ExportKey(EVP_PKEY* key,
- ExportFunction export_fn,
- std::vector<uint8>* output) {
- if (!key)
- return false;
-
- OpenSSLErrStackTracer err_tracer(FROM_HERE);
- ScopedOpenSSL<BIO, BIO_free_all> bio(BIO_new(BIO_s_mem()));
-
- int res = export_fn(bio.get(), key);
- if (!res)
- return false;
-
- char* data = NULL;
- long len = BIO_get_mem_data(bio.get(), &data);
- if (!data || len < 0)
- return false;
-
- STLAssignToVector(output, reinterpret_cast<const uint8*>(data), len);
- return true;
-}
-
-} // namespace
-
-// static
-RSAPrivateKey* RSAPrivateKey::Create(uint16 num_bits) {
- OpenSSLErrStackTracer err_tracer(FROM_HERE);
-
- ScopedOpenSSL<RSA, RSA_free> rsa_key(RSA_new());
- ScopedOpenSSL<BIGNUM, BN_free> bn(BN_new());
- if (!rsa_key.get() || !bn.get() || !BN_set_word(bn.get(), 65537L))
- return NULL;
-
- if (!RSA_generate_key_ex(rsa_key.get(), num_bits, bn.get(), NULL))
- return NULL;
-
- scoped_ptr<RSAPrivateKey> result(new RSAPrivateKey);
- result->key_ = EVP_PKEY_new();
- if (!result->key_ || !EVP_PKEY_set1_RSA(result->key_, rsa_key.get()))
- return NULL;
-
- return result.release();
-}
-
-// static
-RSAPrivateKey* RSAPrivateKey::CreateSensitive(uint16 num_bits) {
- NOTIMPLEMENTED();
- return NULL;
-}
-
-// static
-RSAPrivateKey* RSAPrivateKey::CreateFromPrivateKeyInfo(
- const std::vector<uint8>& input) {
- OpenSSLErrStackTracer err_tracer(FROM_HERE);
-
- // BIO_new_mem_buf is not const aware, but it does not modify the buffer.
- char* data = reinterpret_cast<char*>(const_cast<uint8*>(
- vector_as_array(&input)));
- ScopedOpenSSL<BIO, BIO_free_all> bio(BIO_new_mem_buf(data, input.size()));
- if (!bio.get())
- return NULL;
-
- // Importing is a little more involved than exporting, as we must first
- // PKCS#8 decode the input, and then import the EVP_PKEY from Private Key
- // Info structure returned.
- ScopedOpenSSL<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_free> p8inf(
- d2i_PKCS8_PRIV_KEY_INFO_bio(bio.get(), NULL));
- if (!p8inf.get())
- return NULL;
-
- scoped_ptr<RSAPrivateKey> result(new RSAPrivateKey);
- result->key_ = EVP_PKCS82PKEY(p8inf.get());
- if (!result->key_)
- return NULL;
-
- return result.release();
-}
-
-// static
-RSAPrivateKey* RSAPrivateKey::CreateSensitiveFromPrivateKeyInfo(
- const std::vector<uint8>& input) {
- NOTIMPLEMENTED();
- return NULL;
-}
-
-// static
-RSAPrivateKey* RSAPrivateKey::FindFromPublicKeyInfo(
- const std::vector<uint8>& input) {
- NOTIMPLEMENTED();
- return NULL;
-}
-
-RSAPrivateKey::RSAPrivateKey()
- : key_(NULL) {
-}
-
-RSAPrivateKey::~RSAPrivateKey() {
- if (key_)
- EVP_PKEY_free(key_);
-}
-
-bool RSAPrivateKey::ExportPrivateKey(std::vector<uint8>* output) {
- return ExportKey(key_, i2d_PKCS8PrivateKeyInfo_bio, output);
-}
-
-bool RSAPrivateKey::ExportPublicKey(std::vector<uint8>* output) {
- return ExportKey(key_, i2d_PUBKEY_bio, output);
-}
-
-} // namespace base
diff --git a/base/crypto/rsa_private_key_unittest.cc b/base/crypto/rsa_private_key_unittest.cc
deleted file mode 100644
index 3b0d846..0000000
--- a/base/crypto/rsa_private_key_unittest.cc
+++ /dev/null
@@ -1,383 +0,0 @@
-// Copyright (c) 2009 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.
-
-#include "base/crypto/rsa_private_key.h"
-#include "base/scoped_ptr.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-// Generate random private keys with two different sizes. Reimport, then
-// export them again. We should get back the same exact bytes.
-TEST(RSAPrivateKeyUnitTest, InitRandomTest) {
- scoped_ptr<base::RSAPrivateKey> keypair1(base::RSAPrivateKey::Create(1024));
- scoped_ptr<base::RSAPrivateKey> keypair2(base::RSAPrivateKey::Create(2048));
- ASSERT_TRUE(keypair1.get());
- ASSERT_TRUE(keypair2.get());
-
- std::vector<uint8> privkey1;
- std::vector<uint8> privkey2;
- std::vector<uint8> pubkey1;
- std::vector<uint8> pubkey2;
-
- ASSERT_TRUE(keypair1->ExportPrivateKey(&privkey1));
- ASSERT_TRUE(keypair2->ExportPrivateKey(&privkey2));
- ASSERT_TRUE(keypair1->ExportPublicKey(&pubkey1));
- ASSERT_TRUE(keypair2->ExportPublicKey(&pubkey2));
-
- scoped_ptr<base::RSAPrivateKey> keypair3(
- base::RSAPrivateKey::CreateFromPrivateKeyInfo(privkey1));
- scoped_ptr<base::RSAPrivateKey> keypair4(
- base::RSAPrivateKey::CreateFromPrivateKeyInfo(privkey2));
- ASSERT_TRUE(keypair3.get());
- ASSERT_TRUE(keypair4.get());
-
- std::vector<uint8> privkey3;
- std::vector<uint8> privkey4;
- ASSERT_TRUE(keypair3->ExportPrivateKey(&privkey3));
- ASSERT_TRUE(keypair4->ExportPrivateKey(&privkey4));
-
- ASSERT_EQ(privkey1.size(), privkey3.size());
- ASSERT_EQ(privkey2.size(), privkey4.size());
- ASSERT_TRUE(0 == memcmp(&privkey1.front(), &privkey3.front(),
- privkey1.size()));
- ASSERT_TRUE(0 == memcmp(&privkey2.front(), &privkey4.front(),
- privkey2.size()));
-}
-
-
-// Verify that generated public keys look good. This test data was generated
-// with the openssl command line tool.
-TEST(RSAPrivateKeyUnitTest, PublicKeyTest) {
- const uint8 private_key_info[] = {
- 0x30, 0x82, 0x02, 0x78, 0x02, 0x01, 0x00, 0x30,
- 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
- 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82,
- 0x02, 0x62, 0x30, 0x82, 0x02, 0x5e, 0x02, 0x01,
- 0x00, 0x02, 0x81, 0x81, 0x00, 0xb8, 0x7f, 0x2b,
- 0x20, 0xdc, 0x7c, 0x9b, 0x0c, 0xdc, 0x51, 0x61,
- 0x99, 0x0d, 0x36, 0x0f, 0xd4, 0x66, 0x88, 0x08,
- 0x55, 0x84, 0xd5, 0x3a, 0xbf, 0x2b, 0xa4, 0x64,
- 0x85, 0x7b, 0x0c, 0x04, 0x13, 0x3f, 0x8d, 0xf4,
- 0xbc, 0x38, 0x0d, 0x49, 0xfe, 0x6b, 0xc4, 0x5a,
- 0xb0, 0x40, 0x53, 0x3a, 0xd7, 0x66, 0x09, 0x0f,
- 0x9e, 0x36, 0x74, 0x30, 0xda, 0x8a, 0x31, 0x4f,
- 0x1f, 0x14, 0x50, 0xd7, 0xc7, 0x20, 0x94, 0x17,
- 0xde, 0x4e, 0xb9, 0x57, 0x5e, 0x7e, 0x0a, 0xe5,
- 0xb2, 0x65, 0x7a, 0x89, 0x4e, 0xb6, 0x47, 0xff,
- 0x1c, 0xbd, 0xb7, 0x38, 0x13, 0xaf, 0x47, 0x85,
- 0x84, 0x32, 0x33, 0xf3, 0x17, 0x49, 0xbf, 0xe9,
- 0x96, 0xd0, 0xd6, 0x14, 0x6f, 0x13, 0x8d, 0xc5,
- 0xfc, 0x2c, 0x72, 0xba, 0xac, 0xea, 0x7e, 0x18,
- 0x53, 0x56, 0xa6, 0x83, 0xa2, 0xce, 0x93, 0x93,
- 0xe7, 0x1f, 0x0f, 0xe6, 0x0f, 0x02, 0x03, 0x01,
- 0x00, 0x01, 0x02, 0x81, 0x80, 0x03, 0x61, 0x89,
- 0x37, 0xcb, 0xf2, 0x98, 0xa0, 0xce, 0xb4, 0xcb,
- 0x16, 0x13, 0xf0, 0xe6, 0xaf, 0x5c, 0xc5, 0xa7,
- 0x69, 0x71, 0xca, 0xba, 0x8d, 0xe0, 0x4d, 0xdd,
- 0xed, 0xb8, 0x48, 0x8b, 0x16, 0x93, 0x36, 0x95,
- 0xc2, 0x91, 0x40, 0x65, 0x17, 0xbd, 0x7f, 0xd6,
- 0xad, 0x9e, 0x30, 0x28, 0x46, 0xe4, 0x3e, 0xcc,
- 0x43, 0x78, 0xf9, 0xfe, 0x1f, 0x33, 0x23, 0x1e,
- 0x31, 0x12, 0x9d, 0x3c, 0xa7, 0x08, 0x82, 0x7b,
- 0x7d, 0x25, 0x4e, 0x5e, 0x19, 0xa8, 0x9b, 0xed,
- 0x86, 0xb2, 0xcb, 0x3c, 0xfe, 0x4e, 0xa1, 0xfa,
- 0x62, 0x87, 0x3a, 0x17, 0xf7, 0x60, 0xec, 0x38,
- 0x29, 0xe8, 0x4f, 0x34, 0x9f, 0x76, 0x9d, 0xee,
- 0xa3, 0xf6, 0x85, 0x6b, 0x84, 0x43, 0xc9, 0x1e,
- 0x01, 0xff, 0xfd, 0xd0, 0x29, 0x4c, 0xfa, 0x8e,
- 0x57, 0x0c, 0xc0, 0x71, 0xa5, 0xbb, 0x88, 0x46,
- 0x29, 0x5c, 0xc0, 0x4f, 0x01, 0x02, 0x41, 0x00,
- 0xf5, 0x83, 0xa4, 0x64, 0x4a, 0xf2, 0xdd, 0x8c,
- 0x2c, 0xed, 0xa8, 0xd5, 0x60, 0x5a, 0xe4, 0xc7,
- 0xcc, 0x61, 0xcd, 0x38, 0x42, 0x20, 0xd3, 0x82,
- 0x18, 0xf2, 0x35, 0x00, 0x72, 0x2d, 0xf7, 0x89,
- 0x80, 0x67, 0xb5, 0x93, 0x05, 0x5f, 0xdd, 0x42,
- 0xba, 0x16, 0x1a, 0xea, 0x15, 0xc6, 0xf0, 0xb8,
- 0x8c, 0xbc, 0xbf, 0x54, 0x9e, 0xf1, 0xc1, 0xb2,
- 0xb3, 0x8b, 0xb6, 0x26, 0x02, 0x30, 0xc4, 0x81,
- 0x02, 0x41, 0x00, 0xc0, 0x60, 0x62, 0x80, 0xe1,
- 0x22, 0x78, 0xf6, 0x9d, 0x83, 0x18, 0xeb, 0x72,
- 0x45, 0xd7, 0xc8, 0x01, 0x7f, 0xa9, 0xca, 0x8f,
- 0x7d, 0xd6, 0xb8, 0x31, 0x2b, 0x84, 0x7f, 0x62,
- 0xd9, 0xa9, 0x22, 0x17, 0x7d, 0x06, 0x35, 0x6c,
- 0xf3, 0xc1, 0x94, 0x17, 0x85, 0x5a, 0xaf, 0x9c,
- 0x5c, 0x09, 0x3c, 0xcf, 0x2f, 0x44, 0x9d, 0xb6,
- 0x52, 0x68, 0x5f, 0xf9, 0x59, 0xc8, 0x84, 0x2b,
- 0x39, 0x22, 0x8f, 0x02, 0x41, 0x00, 0xb2, 0x04,
- 0xe2, 0x0e, 0x56, 0xca, 0x03, 0x1a, 0xc0, 0xf9,
- 0x12, 0x92, 0xa5, 0x6b, 0x42, 0xb8, 0x1c, 0xda,
- 0x4d, 0x93, 0x9d, 0x5f, 0x6f, 0xfd, 0xc5, 0x58,
- 0xda, 0x55, 0x98, 0x74, 0xfc, 0x28, 0x17, 0x93,
- 0x1b, 0x75, 0x9f, 0x50, 0x03, 0x7f, 0x7e, 0xae,
- 0xc8, 0x95, 0x33, 0x75, 0x2c, 0xd6, 0xa4, 0x35,
- 0xb8, 0x06, 0x03, 0xba, 0x08, 0x59, 0x2b, 0x17,
- 0x02, 0xdc, 0x4c, 0x7a, 0x50, 0x01, 0x02, 0x41,
- 0x00, 0x9d, 0xdb, 0x39, 0x59, 0x09, 0xe4, 0x30,
- 0xa0, 0x24, 0xf5, 0xdb, 0x2f, 0xf0, 0x2f, 0xf1,
- 0x75, 0x74, 0x0d, 0x5e, 0xb5, 0x11, 0x73, 0xb0,
- 0x0a, 0xaa, 0x86, 0x4c, 0x0d, 0xff, 0x7e, 0x1d,
- 0xb4, 0x14, 0xd4, 0x09, 0x91, 0x33, 0x5a, 0xfd,
- 0xa0, 0x58, 0x80, 0x9b, 0xbe, 0x78, 0x2e, 0x69,
- 0x82, 0x15, 0x7c, 0x72, 0xf0, 0x7b, 0x18, 0x39,
- 0xff, 0x6e, 0xeb, 0xc6, 0x86, 0xf5, 0xb4, 0xc7,
- 0x6f, 0x02, 0x41, 0x00, 0x8d, 0x1a, 0x37, 0x0f,
- 0x76, 0xc4, 0x82, 0xfa, 0x5c, 0xc3, 0x79, 0x35,
- 0x3e, 0x70, 0x8a, 0xbf, 0x27, 0x49, 0xb0, 0x99,
- 0x63, 0xcb, 0x77, 0x5f, 0xa8, 0x82, 0x65, 0xf6,
- 0x03, 0x52, 0x51, 0xf1, 0xae, 0x2e, 0x05, 0xb3,
- 0xc6, 0xa4, 0x92, 0xd1, 0xce, 0x6c, 0x72, 0xfb,
- 0x21, 0xb3, 0x02, 0x87, 0xe4, 0xfd, 0x61, 0xca,
- 0x00, 0x42, 0x19, 0xf0, 0xda, 0x5a, 0x53, 0xe3,
- 0xb1, 0xc5, 0x15, 0xf3
- };
-
- const uint8 expected_public_key_info[] = {
- 0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01,
- 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81,
- 0x89, 0x02, 0x81, 0x81, 0x00, 0xb8, 0x7f, 0x2b,
- 0x20, 0xdc, 0x7c, 0x9b, 0x0c, 0xdc, 0x51, 0x61,
- 0x99, 0x0d, 0x36, 0x0f, 0xd4, 0x66, 0x88, 0x08,
- 0x55, 0x84, 0xd5, 0x3a, 0xbf, 0x2b, 0xa4, 0x64,
- 0x85, 0x7b, 0x0c, 0x04, 0x13, 0x3f, 0x8d, 0xf4,
- 0xbc, 0x38, 0x0d, 0x49, 0xfe, 0x6b, 0xc4, 0x5a,
- 0xb0, 0x40, 0x53, 0x3a, 0xd7, 0x66, 0x09, 0x0f,
- 0x9e, 0x36, 0x74, 0x30, 0xda, 0x8a, 0x31, 0x4f,
- 0x1f, 0x14, 0x50, 0xd7, 0xc7, 0x20, 0x94, 0x17,
- 0xde, 0x4e, 0xb9, 0x57, 0x5e, 0x7e, 0x0a, 0xe5,
- 0xb2, 0x65, 0x7a, 0x89, 0x4e, 0xb6, 0x47, 0xff,
- 0x1c, 0xbd, 0xb7, 0x38, 0x13, 0xaf, 0x47, 0x85,
- 0x84, 0x32, 0x33, 0xf3, 0x17, 0x49, 0xbf, 0xe9,
- 0x96, 0xd0, 0xd6, 0x14, 0x6f, 0x13, 0x8d, 0xc5,
- 0xfc, 0x2c, 0x72, 0xba, 0xac, 0xea, 0x7e, 0x18,
- 0x53, 0x56, 0xa6, 0x83, 0xa2, 0xce, 0x93, 0x93,
- 0xe7, 0x1f, 0x0f, 0xe6, 0x0f, 0x02, 0x03, 0x01,
- 0x00, 0x01
- };
-
- std::vector<uint8> input;
- input.resize(sizeof(private_key_info));
- memcpy(&input.front(), private_key_info, sizeof(private_key_info));
-
- scoped_ptr<base::RSAPrivateKey> key(
- base::RSAPrivateKey::CreateFromPrivateKeyInfo(input));
- ASSERT_TRUE(key.get());
-
- std::vector<uint8> output;
- ASSERT_TRUE(key->ExportPublicKey(&output));
-
- ASSERT_TRUE(
- memcmp(expected_public_key_info, &output.front(), output.size()) == 0);
-}
-
-// These two test keys each contain an integer that has 0x00 for its most
-// significant byte. When encoded as ASN.1, this byte is dropped and there are
-// two interesting sub-cases. When the sign bit of the integer is set, an extra
-// null byte is added back to force the encoded value to be positive. When the
-// sign bit is not set, the encoded integer is just left shorter than usual.
-// See also: http://code.google.com/p/chromium/issues/detail?id=14877.
-//
-// Before we were handling this correctly, we would see one of two failures:
-// * RSAPrivateKey::CreateFromPrivateKeyInfo would return null because the
-// underlying windows API failed to import the key.
-// * The import would succeed, but incorrectly interpret the data. On export,
-// the key would contain different values.
-//
-// This test case verifies these two failures modes don't occur.
-TEST(RSAPrivateKeyUnitTest, ShortIntegers) {
- const uint8 short_integer_with_high_bit[] = {
- 0x30, 0x82, 0x02, 0x77, 0x02, 0x01, 0x00, 0x30,
- 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
- 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82,
- 0x02, 0x61, 0x30, 0x82, 0x02, 0x5d, 0x02, 0x01,
- 0x00, 0x02, 0x81, 0x81, 0x00, 0x92, 0x59, 0x32,
- 0x7d, 0x8e, 0xaf, 0x2e, 0xd5, 0xb2, 0x5c, 0x67,
- 0xc8, 0x7d, 0x48, 0xb7, 0x84, 0x12, 0xd0, 0x76,
- 0xda, 0xe1, 0xa3, 0x1e, 0x40, 0x01, 0x14, 0x5c,
- 0xef, 0x26, 0x6e, 0x28, 0xa2, 0xf7, 0xa5, 0xb4,
- 0x02, 0x37, 0xd0, 0x53, 0x10, 0xcb, 0x7c, 0x6a,
- 0xf4, 0x53, 0x9f, 0xb8, 0xe0, 0x83, 0x93, 0xd1,
- 0x19, 0xd8, 0x28, 0xd1, 0xd1, 0xd8, 0x87, 0x8f,
- 0x92, 0xfd, 0x73, 0xc0, 0x4d, 0x3e, 0x07, 0x22,
- 0x1f, 0xc1, 0x20, 0xb0, 0x70, 0xb2, 0x3b, 0xea,
- 0xb1, 0xe5, 0x0a, 0xfd, 0x56, 0x49, 0x5e, 0x39,
- 0x90, 0x91, 0xce, 0x04, 0x83, 0x29, 0xaa, 0xfd,
- 0x12, 0xa4, 0x42, 0x26, 0x6c, 0x6e, 0x79, 0x70,
- 0x77, 0x03, 0xb2, 0x07, 0x01, 0x3d, 0x85, 0x81,
- 0x95, 0x9e, 0xda, 0x5a, 0xa3, 0xf4, 0x2d, 0x38,
- 0x04, 0x58, 0xf5, 0x6b, 0xc9, 0xf1, 0xb5, 0x65,
- 0xfe, 0x66, 0x0d, 0xa2, 0xd5, 0x02, 0x03, 0x01,
- 0x00, 0x01, 0x02, 0x81, 0x80, 0x5e, 0x01, 0x5f,
- 0xb6, 0x59, 0x1d, 0xdc, 0x36, 0xb6, 0x60, 0x36,
- 0xe6, 0x08, 0xdb, 0xd9, 0xcd, 0xc3, 0x8c, 0x16,
- 0x9c, 0x98, 0x8d, 0x7f, 0xd3, 0xdb, 0x1d, 0xaa,
- 0x68, 0x8f, 0xc5, 0xf8, 0xe2, 0x5d, 0xb3, 0x19,
- 0xc2, 0xc6, 0xf9, 0x51, 0x32, 0x1b, 0x93, 0x6a,
- 0xdc, 0x50, 0x8e, 0xeb, 0x61, 0x84, 0x03, 0x42,
- 0x30, 0x98, 0xb1, 0xf7, 0xbd, 0x14, 0x9a, 0x57,
- 0x36, 0x33, 0x09, 0xd4, 0x3e, 0x90, 0xda, 0xef,
- 0x09, 0x6e, 0xef, 0x49, 0xb6, 0x60, 0x68, 0x5e,
- 0x54, 0x17, 0x25, 0x5b, 0x37, 0xe3, 0x35, 0x63,
- 0x5b, 0x60, 0x3c, 0xbd, 0x50, 0xdf, 0x46, 0x43,
- 0x08, 0xa4, 0x71, 0x21, 0xf1, 0x30, 0x71, 0xdc,
- 0xda, 0xd7, 0x6f, 0xd2, 0x18, 0xbd, 0x39, 0xf1,
- 0xe1, 0xbe, 0xa8, 0x8d, 0x62, 0xdf, 0xa2, 0x3e,
- 0xb6, 0x15, 0x26, 0xb6, 0x57, 0xbd, 0x63, 0xdb,
- 0xc1, 0x91, 0xec, 0xb8, 0x01, 0x02, 0x41, 0x00,
- 0xc6, 0x1a, 0x06, 0x48, 0xf2, 0x12, 0x1c, 0x9f,
- 0x74, 0x20, 0x5c, 0x85, 0xa2, 0xda, 0xe5, 0x62,
- 0x96, 0x8d, 0x22, 0x7b, 0x78, 0x73, 0xea, 0xbb,
- 0x9f, 0x59, 0x42, 0x13, 0x15, 0xc8, 0x11, 0x50,
- 0x6c, 0x55, 0xf6, 0xdf, 0x8b, 0xfe, 0xc7, 0xdd,
- 0xa8, 0xca, 0x54, 0x41, 0xe8, 0xce, 0xbe, 0x7d,
- 0xbd, 0xe2, 0x13, 0x4b, 0x5b, 0x61, 0xeb, 0x69,
- 0x6c, 0xb1, 0x9b, 0x28, 0x68, 0x5b, 0xd6, 0x01,
- 0x02, 0x41, 0x00, 0xbd, 0x1e, 0xfe, 0x51, 0x99,
- 0xb6, 0xe3, 0x84, 0xfe, 0xf1, 0x9e, 0xfd, 0x9c,
- 0xe7, 0x86, 0x43, 0x68, 0x7f, 0x2f, 0x6a, 0x2a,
- 0x4c, 0xae, 0xa6, 0x41, 0x1c, 0xf0, 0x10, 0x37,
- 0x54, 0x23, 0xba, 0x05, 0x0d, 0x18, 0x27, 0x8d,
- 0xb8, 0xe4, 0x8f, 0xf2, 0x25, 0x73, 0x8a, 0xd7,
- 0x05, 0x98, 0x6b, 0x3d, 0x55, 0xb7, 0x6f, 0x7c,
- 0xec, 0x77, 0x61, 0x54, 0x7b, 0xb6, 0x6b, 0x31,
- 0xec, 0x94, 0xd5, 0x02, 0x41, 0x00, 0x90, 0xa2,
- 0xa5, 0x9e, 0x12, 0xa7, 0x68, 0xa0, 0x7e, 0xdf,
- 0xb5, 0xcd, 0x98, 0x26, 0xab, 0xbd, 0xbc, 0x5f,
- 0xd5, 0x22, 0x42, 0xc2, 0x97, 0x4a, 0x5f, 0x40,
- 0x82, 0xfe, 0x7e, 0x33, 0xb1, 0x78, 0x7f, 0x70,
- 0x90, 0x2b, 0x8d, 0x01, 0xfb, 0x18, 0xfa, 0x48,
- 0xa7, 0x15, 0xec, 0x0d, 0x2e, 0x85, 0x8d, 0xe2,
- 0x86, 0xe5, 0xc9, 0x15, 0x88, 0x14, 0x53, 0xd8,
- 0xa4, 0x88, 0xef, 0x10, 0xc6, 0x01, 0x02, 0x41,
- 0x00, 0xba, 0xe4, 0xaf, 0x14, 0xfa, 0xdf, 0xf6,
- 0xd5, 0xce, 0x8f, 0xfe, 0xbb, 0xc8, 0x5c, 0x30,
- 0x9d, 0xda, 0xdd, 0x9d, 0x80, 0xc0, 0x0e, 0x89,
- 0xa5, 0xb8, 0xc1, 0x1d, 0x28, 0x19, 0x55, 0x67,
- 0xfd, 0x03, 0xd2, 0xdd, 0xe4, 0xf0, 0xb4, 0x20,
- 0x03, 0x74, 0x9b, 0xb8, 0x24, 0x23, 0xbb, 0xde,
- 0xd5, 0x53, 0x86, 0xaa, 0xc1, 0x5d, 0x65, 0xdd,
- 0xcf, 0xec, 0x8a, 0x59, 0x4a, 0x73, 0xca, 0xc5,
- 0x85, 0x02, 0x40, 0x00, 0xc4, 0x5e, 0x8d, 0xa4,
- 0xea, 0xbb, 0x6a, 0x9b, 0xe6, 0x3a, 0x4d, 0xc1,
- 0xdb, 0xe5, 0x52, 0x38, 0xf9, 0x59, 0x91, 0x2d,
- 0x90, 0x82, 0xe3, 0x31, 0x1b, 0x48, 0xb7, 0x42,
- 0xfa, 0x1d, 0x83, 0xd5, 0x3d, 0x02, 0xc2, 0x12,
- 0x71, 0x10, 0x3a, 0xbd, 0x92, 0x8f, 0x9b, 0xa2,
- 0x6b, 0x2d, 0x21, 0xa4, 0x65, 0xe9, 0xfa, 0x8c,
- 0x30, 0x2a, 0x89, 0xce, 0xd0, 0xa7, 0x67, 0xd8,
- 0x45, 0x84, 0xb0
- };
-
- const uint8 short_integer_without_high_bit[] = {
- 0x30, 0x82, 0x02, 0x76, 0x02, 0x01, 0x00, 0x30,
- 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
- 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82,
- 0x02, 0x60, 0x30, 0x82, 0x02, 0x5c, 0x02, 0x01,
- 0x00, 0x02, 0x81, 0x81, 0x00, 0xc3, 0x9e, 0x8d,
- 0xc4, 0x6d, 0x38, 0xe8, 0x0e, 0x9f, 0x84, 0x03,
- 0x40, 0x8e, 0x81, 0x2e, 0x56, 0x67, 0x78, 0x11,
- 0x85, 0x27, 0x81, 0x52, 0xf2, 0x1b, 0x3e, 0x5b,
- 0xf8, 0xab, 0xfc, 0xaf, 0xca, 0x5c, 0x26, 0xd5,
- 0xfa, 0xd4, 0x55, 0x50, 0x38, 0xb9, 0x9d, 0x89,
- 0x92, 0x7e, 0x34, 0xcf, 0x37, 0x82, 0x48, 0x2d,
- 0xaa, 0xc4, 0x6a, 0x0e, 0x93, 0xea, 0xad, 0x8a,
- 0x33, 0xf0, 0x42, 0x23, 0xe0, 0x4c, 0x98, 0xbf,
- 0x01, 0x00, 0x1b, 0xfe, 0x06, 0x15, 0xc6, 0xe3,
- 0x80, 0x79, 0x6d, 0xfe, 0x48, 0xcd, 0x40, 0xbb,
- 0xf9, 0x58, 0xe6, 0xbf, 0xd5, 0x4c, 0x29, 0x48,
- 0x53, 0x78, 0x06, 0x03, 0x0d, 0x59, 0xf5, 0x20,
- 0xe0, 0xe6, 0x8c, 0xb2, 0xf5, 0xd8, 0x61, 0x52,
- 0x7e, 0x40, 0x83, 0xd7, 0x69, 0xae, 0xd7, 0x75,
- 0x02, 0x2d, 0x49, 0xd5, 0x15, 0x5b, 0xf1, 0xd9,
- 0x4d, 0x60, 0x7d, 0x62, 0xa5, 0x02, 0x03, 0x01,
- 0x00, 0x01, 0x02, 0x7f, 0x6d, 0x45, 0x23, 0xeb,
- 0x95, 0x17, 0x34, 0x88, 0xf6, 0x91, 0xc7, 0x3f,
- 0x48, 0x5a, 0xe0, 0x87, 0x63, 0x44, 0xae, 0x84,
- 0xb2, 0x8c, 0x8a, 0xc8, 0xb2, 0x6f, 0x22, 0xf0,
- 0xc5, 0x21, 0x61, 0x10, 0xa8, 0x69, 0x09, 0x1e,
- 0x13, 0x7d, 0x94, 0x52, 0x1b, 0x5c, 0xe4, 0x7b,
- 0xf0, 0x03, 0x8f, 0xbc, 0x72, 0x09, 0xdf, 0x78,
- 0x84, 0x3e, 0xb9, 0xe5, 0xe6, 0x31, 0x0a, 0x01,
- 0xf9, 0x32, 0xf8, 0xd6, 0x57, 0xa3, 0x87, 0xe6,
- 0xf5, 0x98, 0xbc, 0x8e, 0x41, 0xb9, 0x50, 0x17,
- 0x7b, 0xd3, 0x97, 0x5a, 0x44, 0x3a, 0xee, 0xff,
- 0x6b, 0xb3, 0x3a, 0x52, 0xe7, 0xa4, 0x96, 0x9a,
- 0xf6, 0x83, 0xc8, 0x97, 0x1c, 0x63, 0xa1, 0xd6,
- 0xb3, 0xa8, 0xb2, 0xc7, 0x73, 0x25, 0x0f, 0x58,
- 0x36, 0xb9, 0x7a, 0x47, 0xa7, 0x4d, 0x30, 0xfe,
- 0x4d, 0x74, 0x56, 0xe8, 0xfb, 0xd6, 0x50, 0xe5,
- 0xe0, 0x28, 0x15, 0x02, 0x41, 0x00, 0xeb, 0x15,
- 0x62, 0xb6, 0x37, 0x41, 0x7c, 0xc5, 0x00, 0x22,
- 0x2c, 0x5a, 0x5e, 0xe4, 0xb2, 0x11, 0x87, 0x89,
- 0xad, 0xf4, 0x57, 0x68, 0x90, 0xb7, 0x9f, 0xe2,
- 0x79, 0x20, 0x6b, 0x98, 0x00, 0x0d, 0x3a, 0x3b,
- 0xc1, 0xcd, 0x36, 0xf9, 0x27, 0xda, 0x40, 0x36,
- 0x1d, 0xb8, 0x5c, 0x96, 0xeb, 0x04, 0x08, 0xe1,
- 0x3f, 0xfa, 0x94, 0x8b, 0x0f, 0xa0, 0xff, 0xc1,
- 0x51, 0xea, 0x90, 0xad, 0x15, 0xc7, 0x02, 0x41,
- 0x00, 0xd5, 0x06, 0x45, 0xd7, 0x55, 0x63, 0x1a,
- 0xf0, 0x89, 0x81, 0xae, 0x87, 0x23, 0xa2, 0x39,
- 0xfe, 0x3d, 0x82, 0xc7, 0xcb, 0x15, 0xb9, 0xe3,
- 0xe2, 0x5b, 0xc6, 0xd2, 0x55, 0xdd, 0xab, 0x55,
- 0x29, 0x7c, 0xda, 0x0e, 0x1c, 0x09, 0xfc, 0x73,
- 0x0d, 0x01, 0xed, 0x6d, 0x2f, 0x05, 0xd0, 0xd5,
- 0x1d, 0xce, 0x18, 0x7f, 0xb0, 0xc8, 0x47, 0x77,
- 0xd2, 0xa9, 0x9e, 0xfc, 0x39, 0x4b, 0x3d, 0x94,
- 0x33, 0x02, 0x41, 0x00, 0x8f, 0x94, 0x09, 0x2d,
- 0x17, 0x44, 0x75, 0x0a, 0xf1, 0x10, 0xee, 0x1b,
- 0xe7, 0xd7, 0x2f, 0xf6, 0xca, 0xdc, 0x49, 0x15,
- 0x72, 0x09, 0x58, 0x51, 0xfe, 0x61, 0xd8, 0xee,
- 0xf7, 0x27, 0xe7, 0xe8, 0x2c, 0x47, 0xf1, 0x0f,
- 0x00, 0x63, 0x5e, 0x76, 0xcb, 0x3f, 0x02, 0x19,
- 0xe6, 0xda, 0xfa, 0x01, 0x05, 0xd7, 0x65, 0x37,
- 0x0b, 0x60, 0x7f, 0x94, 0x2a, 0x80, 0x8d, 0x22,
- 0x81, 0x68, 0x65, 0x63, 0x02, 0x41, 0x00, 0xc2,
- 0xd4, 0x18, 0xde, 0x47, 0x9e, 0xfb, 0x8d, 0x91,
- 0x05, 0xc5, 0x3c, 0x9d, 0xcf, 0x8a, 0x60, 0xc7,
- 0x9b, 0x2b, 0xe5, 0xc6, 0xba, 0x1b, 0xfc, 0xf3,
- 0xd9, 0x54, 0x97, 0xe9, 0xc4, 0x00, 0x80, 0x90,
- 0x4a, 0xd2, 0x6a, 0xbc, 0x8b, 0x62, 0x22, 0x3c,
- 0x68, 0x0c, 0xda, 0xdb, 0xe3, 0xd2, 0x76, 0x8e,
- 0xff, 0x03, 0x12, 0x09, 0x2a, 0xac, 0x21, 0x44,
- 0xb7, 0x3e, 0x91, 0x9c, 0x09, 0xf6, 0xd7, 0x02,
- 0x41, 0x00, 0xc0, 0xa1, 0xbb, 0x70, 0xdc, 0xf8,
- 0xeb, 0x17, 0x61, 0xd4, 0x8c, 0x7c, 0x3b, 0x82,
- 0x91, 0x58, 0xff, 0xf9, 0x19, 0xac, 0x3a, 0x73,
- 0xa7, 0x20, 0xe5, 0x22, 0x02, 0xc4, 0xf6, 0xb9,
- 0xb9, 0x43, 0x53, 0x35, 0x88, 0xe1, 0x05, 0xb6,
- 0x43, 0x9b, 0x39, 0xc8, 0x04, 0x4d, 0x2b, 0x01,
- 0xf7, 0xe6, 0x1b, 0x8d, 0x7e, 0x89, 0xe3, 0x43,
- 0xd4, 0xf3, 0xab, 0x28, 0xd4, 0x5a, 0x1f, 0x20,
- 0xea, 0xbe
- };
-
- std::vector<uint8> input1;
- std::vector<uint8> input2;
-
- input1.resize(sizeof(short_integer_with_high_bit));
- input2.resize(sizeof(short_integer_without_high_bit));
-
- memcpy(&input1.front(), short_integer_with_high_bit,
- sizeof(short_integer_with_high_bit));
- memcpy(&input2.front(), short_integer_without_high_bit,
- sizeof(short_integer_without_high_bit));
-
- scoped_ptr<base::RSAPrivateKey> keypair1(
- base::RSAPrivateKey::CreateFromPrivateKeyInfo(input1));
- scoped_ptr<base::RSAPrivateKey> keypair2(
- base::RSAPrivateKey::CreateFromPrivateKeyInfo(input2));
- ASSERT_TRUE(keypair1.get());
- ASSERT_TRUE(keypair2.get());
-
- std::vector<uint8> output1;
- std::vector<uint8> output2;
- ASSERT_TRUE(keypair1->ExportPrivateKey(&output1));
- ASSERT_TRUE(keypair2->ExportPrivateKey(&output2));
-
- ASSERT_EQ(input1.size(), output1.size());
- ASSERT_EQ(input2.size(), output2.size());
- ASSERT_TRUE(0 == memcmp(&output1.front(), &input1.front(),
- input1.size()));
- ASSERT_TRUE(0 == memcmp(&output2.front(), &input2.front(),
- input2.size()));
-}
diff --git a/base/crypto/rsa_private_key_win.cc b/base/crypto/rsa_private_key_win.cc
deleted file mode 100644
index 6c8a34b..0000000
--- a/base/crypto/rsa_private_key_win.cc
+++ /dev/null
@@ -1,229 +0,0 @@
-// 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.
-
-#include "base/crypto/rsa_private_key.h"
-
-#include <list>
-
-#include "base/logging.h"
-#include "base/scoped_ptr.h"
-#include "base/string_util.h"
-
-namespace {
- // Helper for error handling during key import.
-#define READ_ASSERT(truth) \
- if (!(truth)) { \
- NOTREACHED(); \
- return false; \
- }
-} // namespace
-
-namespace base {
-
-// static
-RSAPrivateKey* RSAPrivateKey::Create(uint16 num_bits) {
- scoped_ptr<RSAPrivateKey> result(new RSAPrivateKey);
- if (!result->InitProvider())
- return NULL;
-
- DWORD flags = CRYPT_EXPORTABLE;
-
- // The size is encoded as the upper 16 bits of the flags. :: sigh ::.
- flags |= (num_bits << 16);
- if (!CryptGenKey(result->provider_, CALG_RSA_SIGN, flags,
- result->key_.receive()))
- return NULL;
-
- return result.release();
-}
-
-// static
-RSAPrivateKey* RSAPrivateKey::CreateSensitive(uint16 num_bits) {
- NOTIMPLEMENTED();
- return NULL;
-}
-
-// static
-RSAPrivateKey* RSAPrivateKey::CreateFromPrivateKeyInfo(
- const std::vector<uint8>& input) {
- scoped_ptr<RSAPrivateKey> result(new RSAPrivateKey);
- if (!result->InitProvider())
- return NULL;
-
- PrivateKeyInfoCodec pki(false); // Little-Endian
- pki.Import(input);
-
- int blob_size = sizeof(PUBLICKEYSTRUC) +
- sizeof(RSAPUBKEY) +
- pki.modulus()->size() +
- pki.prime1()->size() +
- pki.prime2()->size() +
- pki.exponent1()->size() +
- pki.exponent2()->size() +
- pki.coefficient()->size() +
- pki.private_exponent()->size();
- scoped_array<BYTE> blob(new BYTE[blob_size]);
-
- uint8* dest = blob.get();
- PUBLICKEYSTRUC* public_key_struc = reinterpret_cast<PUBLICKEYSTRUC*>(dest);
- public_key_struc->bType = PRIVATEKEYBLOB;
- public_key_struc->bVersion = 0x02;
- public_key_struc->reserved = 0;
- public_key_struc->aiKeyAlg = CALG_RSA_SIGN;
- dest += sizeof(PUBLICKEYSTRUC);
-
- RSAPUBKEY* rsa_pub_key = reinterpret_cast<RSAPUBKEY*>(dest);
- rsa_pub_key->magic = 0x32415352;
- rsa_pub_key->bitlen = pki.modulus()->size() * 8;
- int public_exponent_int = 0;
- for (size_t i = pki.public_exponent()->size(); i > 0; --i) {
- public_exponent_int <<= 8;
- public_exponent_int |= (*pki.public_exponent())[i - 1];
- }
- rsa_pub_key->pubexp = public_exponent_int;
- dest += sizeof(RSAPUBKEY);
-
- memcpy(dest, &pki.modulus()->front(), pki.modulus()->size());
- dest += pki.modulus()->size();
- memcpy(dest, &pki.prime1()->front(), pki.prime1()->size());
- dest += pki.prime1()->size();
- memcpy(dest, &pki.prime2()->front(), pki.prime2()->size());
- dest += pki.prime2()->size();
- memcpy(dest, &pki.exponent1()->front(), pki.exponent1()->size());
- dest += pki.exponent1()->size();
- memcpy(dest, &pki.exponent2()->front(), pki.exponent2()->size());
- dest += pki.exponent2()->size();
- memcpy(dest, &pki.coefficient()->front(), pki.coefficient()->size());
- dest += pki.coefficient()->size();
- memcpy(dest, &pki.private_exponent()->front(),
- pki.private_exponent()->size());
- dest += pki.private_exponent()->size();
-
- READ_ASSERT(dest == blob.get() + blob_size);
- if (!CryptImportKey(result->provider_,
- reinterpret_cast<uint8*>(public_key_struc), blob_size, 0,
- CRYPT_EXPORTABLE, result->key_.receive()))
- return NULL;
-
- return result.release();
-}
-
-// static
-RSAPrivateKey* RSAPrivateKey::CreateSensitiveFromPrivateKeyInfo(
- const std::vector<uint8>& input) {
- NOTIMPLEMENTED();
- return NULL;
-}
-
-// static
-RSAPrivateKey* RSAPrivateKey::FindFromPublicKeyInfo(
- const std::vector<uint8>& input) {
- NOTIMPLEMENTED();
- return NULL;
-}
-
-RSAPrivateKey::RSAPrivateKey() : provider_(NULL), key_(NULL) {}
-
-RSAPrivateKey::~RSAPrivateKey() {}
-
-bool RSAPrivateKey::InitProvider() {
- return FALSE != CryptAcquireContext(provider_.receive(), NULL, NULL,
- PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
-}
-
-bool RSAPrivateKey::ExportPrivateKey(std::vector<uint8>* output) {
- // Export the key
- DWORD blob_length = 0;
- if (!CryptExportKey(key_, 0, PRIVATEKEYBLOB, 0, NULL, &blob_length)) {
- NOTREACHED();
- return false;
- }
-
- scoped_array<uint8> blob(new uint8[blob_length]);
- if (!CryptExportKey(key_, 0, PRIVATEKEYBLOB, 0, blob.get(), &blob_length)) {
- NOTREACHED();
- return false;
- }
-
- uint8* pos = blob.get();
- PUBLICKEYSTRUC *publickey_struct = reinterpret_cast<PUBLICKEYSTRUC*>(pos);
- pos += sizeof(PUBLICKEYSTRUC);
-
- RSAPUBKEY *rsa_pub_key = reinterpret_cast<RSAPUBKEY*>(pos);
- pos += sizeof(RSAPUBKEY);
-
- int mod_size = rsa_pub_key->bitlen / 8;
- int primes_size = rsa_pub_key->bitlen / 16;
-
- PrivateKeyInfoCodec pki(false); // Little-Endian
-
- pki.modulus()->assign(pos, pos + mod_size);
- pos += mod_size;
-
- pki.prime1()->assign(pos, pos + primes_size);
- pos += primes_size;
- pki.prime2()->assign(pos, pos + primes_size);
- pos += primes_size;
-
- pki.exponent1()->assign(pos, pos + primes_size);
- pos += primes_size;
- pki.exponent2()->assign(pos, pos + primes_size);
- pos += primes_size;
-
- pki.coefficient()->assign(pos, pos + primes_size);
- pos += primes_size;
-
- pki.private_exponent()->assign(pos, pos + mod_size);
- pos += mod_size;
-
- pki.public_exponent()->assign(reinterpret_cast<uint8*>(&rsa_pub_key->pubexp),
- reinterpret_cast<uint8*>(&rsa_pub_key->pubexp) + 4);
-
- CHECK_EQ(pos - blob_length, reinterpret_cast<BYTE*>(publickey_struct));
-
- return pki.Export(output);
-}
-
-bool RSAPrivateKey::ExportPublicKey(std::vector<uint8>* output) {
- DWORD key_info_len;
- if (!CryptExportPublicKeyInfo(
- provider_, AT_SIGNATURE, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
- NULL, &key_info_len)) {
- NOTREACHED();
- return false;
- }
-
- scoped_array<uint8> key_info(new uint8[key_info_len]);
- if (!CryptExportPublicKeyInfo(
- provider_, AT_SIGNATURE, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
- reinterpret_cast<CERT_PUBLIC_KEY_INFO*>(key_info.get()), &key_info_len)) {
- NOTREACHED();
- return false;
- }
-
- DWORD encoded_length;
- if (!CryptEncodeObject(
- X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, X509_PUBLIC_KEY_INFO,
- reinterpret_cast<CERT_PUBLIC_KEY_INFO*>(key_info.get()), NULL,
- &encoded_length)) {
- NOTREACHED();
- return false;
- }
-
- scoped_array<BYTE> encoded(new BYTE[encoded_length]);
- if (!CryptEncodeObject(
- X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, X509_PUBLIC_KEY_INFO,
- reinterpret_cast<CERT_PUBLIC_KEY_INFO*>(key_info.get()), encoded.get(),
- &encoded_length)) {
- NOTREACHED();
- return false;
- }
-
- for (size_t i = 0; i < encoded_length; ++i)
- output->push_back(encoded[i]);
-
- return true;
-}
-
-} // namespace base
diff --git a/base/crypto/scoped_capi_types.h b/base/crypto/scoped_capi_types.h
deleted file mode 100644
index d6582a7..0000000
--- a/base/crypto/scoped_capi_types.h
+++ /dev/null
@@ -1,125 +0,0 @@
-// 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 BASE_CRYPTO_SCOPED_CAPI_TYPES_H_
-#define BASE_CRYPTO_SCOPED_CAPI_TYPES_H_
-#pragma once
-
-#include <windows.h>
-#include <wincrypt.h>
-
-#include <algorithm>
-
-#include "base/logging.h"
-
-namespace base {
-
-// Simple destructor for the Free family of CryptoAPI functions, such as
-// CryptDestroyHash, which take only a single argument to release.
-template <typename CAPIHandle, BOOL (WINAPI *Destroyer)(CAPIHandle)>
-struct CAPIDestroyer {
- void operator()(CAPIHandle handle) const {
- if (handle) {
- BOOL ok = Destroyer(handle);
- DCHECK(ok);
- }
- }
-};
-
-// Destructor for the Close/Release family of CryptoAPI functions, which take
-// a second DWORD parameter indicating flags to use when closing or releasing.
-// This includes functions like CertCloseStore or CryptReleaseContext.
-template <typename CAPIHandle, BOOL (WINAPI *Destroyer)(CAPIHandle, DWORD),
- DWORD flags>
-struct CAPIDestroyerWithFlags {
- void operator()(CAPIHandle handle) const {
- if (handle) {
- BOOL ok = Destroyer(handle, flags);
- DCHECK(ok);
- }
- }
-};
-
-// scoped_ptr-like class for the CryptoAPI cryptography and certificate
-// handles. Because these handles are defined as integer types, and not
-// pointers, the existing scoped classes, such as scoped_ptr_malloc, are
-// insufficient. The semantics are the same as scoped_ptr.
-template <class CAPIHandle, typename FreeProc>
-class ScopedCAPIHandle {
- public:
- explicit ScopedCAPIHandle(CAPIHandle handle = NULL) : handle_(handle) {}
-
- ~ScopedCAPIHandle() {
- free_(handle_);
- }
-
- void reset(CAPIHandle handle = NULL) {
- if (handle_ != handle) {
- free_(handle_);
- handle_ = handle;
- }
- }
-
- operator CAPIHandle() const { return handle_; }
- CAPIHandle get() const { return handle_; }
-
- CAPIHandle* receive() {
- CHECK(handle_ == NULL);
- return &handle_;
- }
-
- bool operator==(CAPIHandle handle) const {
- return handle_ == handle;
- }
-
- bool operator!=(CAPIHandle handle) const {
- return handle_ != handle;
- }
-
- void swap(ScopedCAPIHandle& b) {
- CAPIHandle tmp = b.handle_;
- b.handle_ = handle_;
- handle_ = tmp;
- }
-
- CAPIHandle release() {
- CAPIHandle tmp = handle_;
- handle_ = NULL;
- return tmp;
- }
-
- private:
- CAPIHandle handle_;
- static const FreeProc free_;
-
- DISALLOW_COPY_AND_ASSIGN(ScopedCAPIHandle);
-};
-
-template<class CH, typename FP>
-const FP ScopedCAPIHandle<CH, FP>::free_ = FP();
-
-template<class CH, typename FP> inline
-bool operator==(CH h, const ScopedCAPIHandle<CH, FP>& b) {
- return h == b.get();
-}
-
-template<class CH, typename FP> inline
-bool operator!=(CH h, const ScopedCAPIHandle<CH, FP>& b) {
- return h != b.get();
-}
-
-typedef ScopedCAPIHandle<
- HCRYPTPROV,
- CAPIDestroyerWithFlags<HCRYPTPROV,
- CryptReleaseContext, 0> > ScopedHCRYPTPROV;
-
-typedef ScopedCAPIHandle<
- HCRYPTKEY, CAPIDestroyer<HCRYPTKEY, CryptDestroyKey> > ScopedHCRYPTKEY;
-
-typedef ScopedCAPIHandle<
- HCRYPTHASH, CAPIDestroyer<HCRYPTHASH, CryptDestroyHash> > ScopedHCRYPTHASH;
-
-} // namespace base
-
-#endif // BASE_CRYPTO_SCOPED_CAPI_TYPES_H_
diff --git a/base/crypto/scoped_nss_types.h b/base/crypto/scoped_nss_types.h
deleted file mode 100644
index 664251f..0000000
--- a/base/crypto/scoped_nss_types.h
+++ /dev/null
@@ -1,52 +0,0 @@
-// 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 BASE_SCOPED_NSS_TYPES_H_
-#define BASE_SCOPED_NSS_TYPES_H_
-#pragma once
-
-#include <nss.h>
-#include <pk11pub.h>
-
-#include "base/scoped_ptr.h"
-
-namespace base {
-
-template <typename Type, void (*Destroyer)(Type*)>
-struct NSSDestroyer {
- void operator()(Type* ptr) const {
- if (ptr)
- Destroyer(ptr);
- }
-};
-
-template <typename Type, void (*Destroyer)(Type*, PRBool), PRBool freeit>
-struct NSSDestroyer1 {
- void operator()(Type* ptr) const {
- if (ptr)
- Destroyer(ptr, freeit);
- }
-};
-
-// Define some convenient scopers around NSS pointers.
-typedef scoped_ptr_malloc<
- PK11Context, NSSDestroyer1<PK11Context,
- PK11_DestroyContext,
- PR_TRUE> > ScopedPK11Context;
-typedef scoped_ptr_malloc<
- PK11SlotInfo, NSSDestroyer<PK11SlotInfo, PK11_FreeSlot> > ScopedPK11Slot;
-typedef scoped_ptr_malloc<
- PK11SymKey, NSSDestroyer<PK11SymKey, PK11_FreeSymKey> > ScopedPK11SymKey;
-typedef scoped_ptr_malloc<
- SECAlgorithmID, NSSDestroyer1<SECAlgorithmID,
- SECOID_DestroyAlgorithmID,
- PR_TRUE> > ScopedSECAlgorithmID;
-typedef scoped_ptr_malloc<
- SECItem, NSSDestroyer1<SECItem,
- SECITEM_FreeItem,
- PR_TRUE> > ScopedSECItem;
-
-} // namespace base
-
-#endif // BASE_SCOPED_NSS_TYPES_H_
diff --git a/base/crypto/secure_hash.h b/base/crypto/secure_hash.h
deleted file mode 100644
index 3759218..0000000
--- a/base/crypto/secure_hash.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright (c) 2011 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 BASE_CRYPTO_SECURE_HASH_H_
-#define BASE_CRYPTO_SECURE_HASH_H_
-#pragma once
-
-#include "base/basictypes.h"
-
-namespace base {
-
-// A wrapper to calculate secure hashes incrementally, allowing to
-// be used when the full input is not known in advance.
-class SecureHash {
- public:
- enum Algorithm {
- SHA256,
- };
- virtual ~SecureHash() {}
-
- static SecureHash* Create(Algorithm type);
-
- virtual void Update(const void* input, size_t len) = 0;
- virtual void Finish(void* output, size_t len) = 0;
-
- protected:
- SecureHash() {}
-
- private:
- DISALLOW_COPY_AND_ASSIGN(SecureHash);
-};
-
-} // namespace base
-
-#endif // BASE_CRYPTO_SECURE_HASH_H_
diff --git a/base/crypto/secure_hash_default.cc b/base/crypto/secure_hash_default.cc
deleted file mode 100644
index 436867e..0000000
--- a/base/crypto/secure_hash_default.cc
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright (c) 2011 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.
-
-#include "base/crypto/secure_hash.h"
-
-#include "base/logging.h"
-#include "base/third_party/nss/blapi.h"
-#include "base/third_party/nss/sha256.h"
-
-namespace base {
-
-namespace {
-
-class SecureHashSHA256NSS : public SecureHash {
- public:
- SecureHashSHA256NSS() {
- SHA256_Begin(&ctx_);
- }
-
- virtual ~SecureHashSHA256NSS() {
- }
-
- virtual void Update(const void* input, size_t len) {
- SHA256_Update(&ctx_, static_cast<const unsigned char*>(input), len);
- }
-
- virtual void Finish(void* output, size_t len) {
- SHA256_End(&ctx_, static_cast<unsigned char*>(output), NULL,
- static_cast<unsigned int>(len));
- }
-
- private:
- SHA256Context ctx_;
-};
-
-} // namespace
-
-SecureHash* SecureHash::Create(Algorithm algorithm) {
- switch (algorithm) {
- case SHA256:
- return new SecureHashSHA256NSS();
- default:
- NOTIMPLEMENTED();
- return NULL;
- }
-}
-
-} // namespace base
diff --git a/base/crypto/secure_hash_openssl.cc b/base/crypto/secure_hash_openssl.cc
deleted file mode 100644
index 8087279..0000000
--- a/base/crypto/secure_hash_openssl.cc
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright (c) 2011 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.
-
-#include "base/crypto/secure_hash.h"
-
-#include <openssl/ssl.h>
-
-#include "base/basictypes.h"
-#include "base/logging.h"
-#include "base/openssl_util.h"
-
-namespace base {
-
-namespace {
-
-class SecureHashSHA256OpenSSL : public SecureHash {
- public:
- SecureHashSHA256OpenSSL() {
- SHA256_Init(&ctx_);
- }
-
- virtual ~SecureHashSHA256OpenSSL() {
- OPENSSL_cleanse(&ctx_, sizeof(ctx_));
- }
-
- virtual void Update(const void* input, size_t len) {
- SHA256_Update(&ctx_, static_cast<const unsigned char*>(input), len);
- }
-
- virtual void Finish(void* output, size_t len) {
- ScopedOpenSSLSafeSizeBuffer<SHA256_DIGEST_LENGTH> result(
- static_cast<unsigned char*>(output), len);
- SHA256_Final(result.safe_buffer(), &ctx_);
- }
-
- private:
- SHA256_CTX ctx_;
-};
-
-} // namespace
-
-SecureHash* SecureHash::Create(Algorithm algorithm) {
- switch (algorithm) {
- case SHA256:
- return new SecureHashSHA256OpenSSL();
- default:
- NOTIMPLEMENTED();
- return NULL;
- }
-}
-
-} // namespace base
diff --git a/base/crypto/secure_hash_unittest.cc b/base/crypto/secure_hash_unittest.cc
deleted file mode 100644
index 2dac928..0000000
--- a/base/crypto/secure_hash_unittest.cc
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright (c) 2011 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.
-
-#include "base/crypto/secure_hash.h"
-
-#include "base/basictypes.h"
-#include "base/scoped_ptr.h"
-#include "base/sha2.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-TEST(SecureHashTest, TestUpdate) {
- // Example B.3 from FIPS 180-2: long message.
- std::string input3(500000, 'a'); // 'a' repeated half a million times
- int expected3[] = { 0xcd, 0xc7, 0x6e, 0x5c,
- 0x99, 0x14, 0xfb, 0x92,
- 0x81, 0xa1, 0xc7, 0xe2,
- 0x84, 0xd7, 0x3e, 0x67,
- 0xf1, 0x80, 0x9a, 0x48,
- 0xa4, 0x97, 0x20, 0x0e,
- 0x04, 0x6d, 0x39, 0xcc,
- 0xc7, 0x11, 0x2c, 0xd0 };
-
- uint8 output3[base::SHA256_LENGTH];
-
- scoped_ptr<base::SecureHash> ctx(base::SecureHash::Create(
- base::SecureHash::SHA256));
- ctx->Update(input3.data(), input3.size());
- ctx->Update(input3.data(), input3.size());
-
- ctx->Finish(output3, sizeof(output3));
- for (size_t i = 0; i < base::SHA256_LENGTH; i++)
- EXPECT_EQ(expected3[i], static_cast<int>(output3[i]));
-}
diff --git a/base/crypto/signature_creator.h b/base/crypto/signature_creator.h
deleted file mode 100644
index 3e3afd2..0000000
--- a/base/crypto/signature_creator.h
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright (c) 2011 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 BASE_CRYPTO_SIGNATURE_CREATOR_H_
-#define BASE_CRYPTO_SIGNATURE_CREATOR_H_
-#pragma once
-
-#include "build/build_config.h"
-
-#if defined(USE_OPENSSL)
-// Forward declaration for openssl/*.h
-typedef struct env_md_ctx_st EVP_MD_CTX;
-#elif defined(USE_NSS)
-// Forward declaration.
-struct SGNContextStr;
-#elif defined(OS_MACOSX)
-#include <Security/cssm.h>
-#endif
-
-#include <vector>
-
-#include "base/basictypes.h"
-#include "base/crypto/rsa_private_key.h"
-
-#if defined(OS_WIN)
-#include "base/crypto/scoped_capi_types.h"
-#endif
-
-namespace base {
-
-// Signs data using a bare private key (as opposed to a full certificate).
-// Currently can only sign data using SHA-1 with RSA encryption.
-class SignatureCreator {
- public:
- ~SignatureCreator();
-
- // Create an instance. The caller must ensure that the provided PrivateKey
- // instance outlives the created SignatureCreator.
- static SignatureCreator* Create(RSAPrivateKey* key);
-
- // Update the signature with more data.
- bool Update(const uint8* data_part, int data_part_len);
-
- // Finalize the signature.
- bool Final(std::vector<uint8>* signature);
-
- private:
- // Private constructor. Use the Create() method instead.
- SignatureCreator();
-
- RSAPrivateKey* key_;
-
-#if defined(USE_OPENSSL)
- EVP_MD_CTX* sign_context_;
-#elif defined(USE_NSS)
- SGNContextStr* sign_context_;
-#elif defined(OS_MACOSX)
- CSSM_CC_HANDLE sig_handle_;
-#elif defined(OS_WIN)
- ScopedHCRYPTHASH hash_object_;
-#endif
-
- DISALLOW_COPY_AND_ASSIGN(SignatureCreator);
-};
-
-} // namespace base
-
-#endif // BASE_CRYPTO_SIGNATURE_CREATOR_H_
diff --git a/base/crypto/signature_creator_mac.cc b/base/crypto/signature_creator_mac.cc
deleted file mode 100644
index 1001c64..0000000
--- a/base/crypto/signature_creator_mac.cc
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright (c) 2009 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.
-
-#include "base/crypto/signature_creator.h"
-
-#include <stdlib.h>
-
-#include "base/crypto/cssm_init.h"
-#include "base/logging.h"
-#include "base/scoped_ptr.h"
-
-namespace base {
-
-// static
-SignatureCreator* SignatureCreator::Create(RSAPrivateKey* key) {
- scoped_ptr<SignatureCreator> result(new SignatureCreator);
- result->key_ = key;
-
- CSSM_RETURN crtn;
- crtn = CSSM_CSP_CreateSignatureContext(GetSharedCSPHandle(),
- CSSM_ALGID_SHA1WithRSA,
- NULL,
- key->key(),
- &result->sig_handle_);
- if (crtn) {
- NOTREACHED();
- return NULL;
- }
-
- crtn = CSSM_SignDataInit(result->sig_handle_);
- if (crtn) {
- NOTREACHED();
- return NULL;
- }
-
- return result.release();
-}
-
-SignatureCreator::SignatureCreator() : sig_handle_(0) {
- EnsureCSSMInit();
-}
-
-SignatureCreator::~SignatureCreator() {
- CSSM_RETURN crtn;
- if (sig_handle_) {
- crtn = CSSM_DeleteContext(sig_handle_);
- DCHECK(crtn == CSSM_OK);
- }
-}
-
-bool SignatureCreator::Update(const uint8* data_part, int data_part_len) {
- CSSM_DATA data;
- data.Data = const_cast<uint8*>(data_part);
- data.Length = data_part_len;
- CSSM_RETURN crtn = CSSM_SignDataUpdate(sig_handle_, &data, 1);
- DCHECK(crtn == CSSM_OK);
- return true;
-}
-
-bool SignatureCreator::Final(std::vector<uint8>* signature) {
- ScopedCSSMData sig;
- CSSM_RETURN crtn = CSSM_SignDataFinal(sig_handle_, sig);
-
- if (crtn) {
- NOTREACHED();
- return false;
- }
-
- signature->assign(sig->Data, sig->Data + sig->Length);
- return true;
-}
-
-} // namespace base
diff --git a/base/crypto/signature_creator_nss.cc b/base/crypto/signature_creator_nss.cc
deleted file mode 100644
index 4cc2c10..0000000
--- a/base/crypto/signature_creator_nss.cc
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright (c) 2009 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.
-
-#include "base/crypto/signature_creator.h"
-
-#include <cryptohi.h>
-#include <keyhi.h>
-#include <stdlib.h>
-
-#include "base/logging.h"
-#include "base/nss_util.h"
-#include "base/scoped_ptr.h"
-
-namespace base {
-
-SignatureCreator::~SignatureCreator() {
- if (sign_context_) {
- SGN_DestroyContext(sign_context_, PR_TRUE);
- sign_context_ = NULL;
- }
-}
-
-// static
-SignatureCreator* SignatureCreator::Create(RSAPrivateKey* key) {
- scoped_ptr<SignatureCreator> result(new SignatureCreator);
- result->key_ = key;
-
- result->sign_context_ = SGN_NewContext(SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION,
- key->key());
- if (!result->sign_context_) {
- NOTREACHED();
- return NULL;
- }
-
- SECStatus rv = SGN_Begin(result->sign_context_);
- if (rv != SECSuccess) {
- NOTREACHED();
- return NULL;
- }
-
- return result.release();
-}
-
-bool SignatureCreator::Update(const uint8* data_part, int data_part_len) {
- // TODO(wtc): Remove this const_cast when we require NSS 3.12.5.
- // See NSS bug https://bugzilla.mozilla.org/show_bug.cgi?id=518255
- SECStatus rv = SGN_Update(sign_context_,
- const_cast<unsigned char*>(data_part),
- data_part_len);
- if (rv != SECSuccess) {
- NOTREACHED();
- return false;
- }
-
- return true;
-}
-
-bool SignatureCreator::Final(std::vector<uint8>* signature) {
- SECItem signature_item;
- SECStatus rv = SGN_End(sign_context_, &signature_item);
- if (rv != SECSuccess) {
- NOTREACHED();
- return false;
- }
- signature->assign(signature_item.data,
- signature_item.data + signature_item.len);
- SECITEM_FreeItem(&signature_item, PR_FALSE);
- return true;
-}
-
-SignatureCreator::SignatureCreator() : sign_context_(NULL) {
- EnsureNSSInit();
-}
-
-} // namespace base
diff --git a/base/crypto/signature_creator_openssl.cc b/base/crypto/signature_creator_openssl.cc
deleted file mode 100644
index 5bdb783..0000000
--- a/base/crypto/signature_creator_openssl.cc
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright (c) 2009 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.
-
-#include "base/crypto/signature_creator.h"
-
-#include <openssl/evp.h>
-
-#include "base/logging.h"
-#include "base/openssl_util.h"
-#include "base/scoped_ptr.h"
-#include "base/stl_util-inl.h"
-
-namespace base {
-
-// static
-SignatureCreator* SignatureCreator::Create(RSAPrivateKey* key) {
- OpenSSLErrStackTracer err_tracer(FROM_HERE);
- scoped_ptr<SignatureCreator> result(new SignatureCreator);
- result->key_ = key;
- if (!EVP_SignInit_ex(result->sign_context_, EVP_sha1(), NULL))
- return NULL;
- return result.release();
-}
-
-SignatureCreator::SignatureCreator()
- : sign_context_(EVP_MD_CTX_create()) {
-}
-
-SignatureCreator::~SignatureCreator() {
- EVP_MD_CTX_destroy(sign_context_);
-}
-
-bool SignatureCreator::Update(const uint8* data_part, int data_part_len) {
- OpenSSLErrStackTracer err_tracer(FROM_HERE);
- return EVP_SignUpdate(sign_context_, data_part, data_part_len) == 1;
-}
-
-bool SignatureCreator::Final(std::vector<uint8>* signature) {
- OpenSSLErrStackTracer err_tracer(FROM_HERE);
- EVP_PKEY* key = key_->key();
- signature->resize(EVP_PKEY_size(key));
-
- unsigned int len = 0;
- int rv = EVP_SignFinal(sign_context_, vector_as_array(signature), &len, key);
- if (!rv) {
- signature->clear();
- return false;
- }
- signature->resize(len);
- return true;
-}
-
-} // namespace base
diff --git a/base/crypto/signature_creator_unittest.cc b/base/crypto/signature_creator_unittest.cc
deleted file mode 100644
index 11959cb..0000000
--- a/base/crypto/signature_creator_unittest.cc
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright (c) 2009 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.
-
-#include <vector>
-
-#include "base/crypto/signature_creator.h"
-#include "base/crypto/signature_verifier.h"
-#include "base/scoped_ptr.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-TEST(SignatureCreatorTest, BasicTest) {
- // Do a verify round trip.
- scoped_ptr<base::RSAPrivateKey> key_original(
- base::RSAPrivateKey::Create(1024));
- ASSERT_TRUE(key_original.get());
-
- std::vector<uint8> key_info;
- key_original->ExportPrivateKey(&key_info);
- scoped_ptr<base::RSAPrivateKey> key(
- base::RSAPrivateKey::CreateFromPrivateKeyInfo(key_info));
- ASSERT_TRUE(key.get());
-
- scoped_ptr<base::SignatureCreator> signer(
- base::SignatureCreator::Create(key.get()));
- ASSERT_TRUE(signer.get());
-
- std::string data("Hello, World!");
- ASSERT_TRUE(signer->Update(reinterpret_cast<const uint8*>(data.c_str()),
- data.size()));
-
- std::vector<uint8> signature;
- ASSERT_TRUE(signer->Final(&signature));
-
- std::vector<uint8> public_key_info;
- ASSERT_TRUE(key_original->ExportPublicKey(&public_key_info));
-
- // This is the algorithm ID for SHA-1 with RSA encryption.
- // TODO(aa): Factor this out into some shared location.
- const uint8 kSHA1WithRSAAlgorithmID[] = {
- 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
- 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00
- };
- base::SignatureVerifier verifier;
- ASSERT_TRUE(verifier.VerifyInit(
- kSHA1WithRSAAlgorithmID, sizeof(kSHA1WithRSAAlgorithmID),
- &signature.front(), signature.size(),
- &public_key_info.front(), public_key_info.size()));
-
- verifier.VerifyUpdate(reinterpret_cast<const uint8*>(data.c_str()),
- data.size());
- ASSERT_TRUE(verifier.VerifyFinal());
-}
diff --git a/base/crypto/signature_creator_win.cc b/base/crypto/signature_creator_win.cc
deleted file mode 100644
index 45924f0..0000000
--- a/base/crypto/signature_creator_win.cc
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright (c) 2009 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.
-
-#include "base/crypto/signature_creator.h"
-
-#include "base/logging.h"
-#include "base/scoped_ptr.h"
-
-namespace base {
-
-// static
-SignatureCreator* SignatureCreator::Create(RSAPrivateKey* key) {
- scoped_ptr<SignatureCreator> result(new SignatureCreator);
- result->key_ = key;
-
- if (!CryptCreateHash(key->provider(), CALG_SHA1, 0, 0,
- result->hash_object_.receive())) {
- NOTREACHED();
- return NULL;
- }
-
- return result.release();
-}
-
-SignatureCreator::SignatureCreator() : hash_object_(0) {}
-
-SignatureCreator::~SignatureCreator() {}
-
-bool SignatureCreator::Update(const uint8* data_part, int data_part_len) {
- if (!CryptHashData(hash_object_, data_part, data_part_len, 0)) {
- NOTREACHED();
- return false;
- }
-
- return true;
-}
-
-bool SignatureCreator::Final(std::vector<uint8>* signature) {
- DWORD signature_length = 0;
- if (!CryptSignHash(hash_object_, AT_SIGNATURE, NULL, 0, NULL,
- &signature_length)) {
- return false;
- }
-
- std::vector<uint8> temp;
- temp.resize(signature_length);
- if (!CryptSignHash(hash_object_, AT_SIGNATURE, NULL, 0, &temp.front(),
- &signature_length)) {
- return false;
- }
-
- temp.resize(signature_length);
- for (size_t i = temp.size(); i > 0; --i)
- signature->push_back(temp[i - 1]);
-
- return true;
-}
-
-} // namespace base
diff --git a/base/crypto/signature_verifier.h b/base/crypto/signature_verifier.h
deleted file mode 100644
index e2b61af..0000000
--- a/base/crypto/signature_verifier.h
+++ /dev/null
@@ -1,108 +0,0 @@
-// Copyright (c) 2009 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 BASE_CRYPTO_SIGNATURE_VERIFIER_H_
-#define BASE_CRYPTO_SIGNATURE_VERIFIER_H_
-#pragma once
-
-#include "build/build_config.h"
-
-#if defined(USE_NSS)
-#include <cryptoht.h>
-#elif defined(OS_MACOSX)
-#include <Security/cssm.h>
-#endif
-
-#include <vector>
-
-#include "base/basictypes.h"
-
-#if defined(OS_WIN)
-#include "base/crypto/scoped_capi_types.h"
-#endif
-
-namespace base {
-
-// The SignatureVerifier class verifies a signature using a bare public key
-// (as opposed to a certificate).
-class SignatureVerifier {
- public:
- SignatureVerifier();
- ~SignatureVerifier();
-
- // Streaming interface:
-
- // Initiates a signature verification operation. This should be followed
- // by one or more VerifyUpdate calls and a VerifyFinal call.
- //
- // The signature algorithm is specified as a DER encoded ASN.1
- // AlgorithmIdentifier structure:
- // AlgorithmIdentifier ::= SEQUENCE {
- // algorithm OBJECT IDENTIFIER,
- // parameters ANY DEFINED BY algorithm OPTIONAL }
- //
- // The signature is encoded according to the signature algorithm, but it
- // must not be further encoded in an ASN.1 BIT STRING.
- // Note: An RSA signatures is actually a big integer. It must be in the
- // big-endian byte order.
- //
- // The public key is specified as a DER encoded ASN.1 SubjectPublicKeyInfo
- // structure, which contains not only the public key but also its type
- // (algorithm):
- // SubjectPublicKeyInfo ::= SEQUENCE {
- // algorithm AlgorithmIdentifier,
- // subjectPublicKey BIT STRING }
- bool VerifyInit(const uint8* signature_algorithm,
- int signature_algorithm_len,
- const uint8* signature,
- int signature_len,
- const uint8* public_key_info,
- int public_key_info_len);
-
- // Feeds a piece of the data to the signature verifier.
- void VerifyUpdate(const uint8* data_part, int data_part_len);
-
- // Concludes a signature verification operation. Returns true if the
- // signature is valid. Returns false if the signature is invalid or an
- // error occurred.
- bool VerifyFinal();
-
- // Note: we can provide a one-shot interface if there is interest:
- // bool Verify(const uint8* data,
- // int data_len,
- // const uint8* signature_algorithm,
- // int signature_algorithm_len,
- // const uint8* signature,
- // int signature_len,
- // const uint8* public_key_info,
- // int public_key_info_len);
-
- private:
- void Reset();
-
- std::vector<uint8> signature_;
-
-#if defined(USE_OPENSSL)
- struct VerifyContext;
- VerifyContext* verify_context_;
-#elif defined(USE_NSS)
- VFYContext* vfy_context_;
-#elif defined(OS_MACOSX)
- std::vector<uint8> public_key_info_;
-
- CSSM_CC_HANDLE sig_handle_;
-
- CSSM_KEY public_key_;
-#elif defined(OS_WIN)
- ScopedHCRYPTPROV provider_;
-
- ScopedHCRYPTHASH hash_object_;
-
- ScopedHCRYPTKEY public_key_;
-#endif
-};
-
-} // namespace base
-
-#endif // BASE_CRYPTO_SIGNATURE_VERIFIER_H_
diff --git a/base/crypto/signature_verifier_mac.cc b/base/crypto/signature_verifier_mac.cc
deleted file mode 100644
index c8bfa8b..0000000
--- a/base/crypto/signature_verifier_mac.cc
+++ /dev/null
@@ -1,105 +0,0 @@
-// Copyright (c) 2009 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.
-
-#include "base/crypto/signature_verifier.h"
-
-#include <stdlib.h>
-
-#include "base/crypto/cssm_init.h"
-#include "base/logging.h"
-
-namespace base {
-
-SignatureVerifier::SignatureVerifier() : sig_handle_(0) {
- EnsureCSSMInit();
-}
-
-SignatureVerifier::~SignatureVerifier() {
- Reset();
-}
-
-bool SignatureVerifier::VerifyInit(const uint8* signature_algorithm,
- int signature_algorithm_len,
- const uint8* signature,
- int signature_len,
- const uint8* public_key_info,
- int public_key_info_len) {
- signature_.assign(signature, signature + signature_len);
- public_key_info_.assign(public_key_info,
- public_key_info + public_key_info_len);
-
- CSSM_ALGORITHMS key_alg = CSSM_ALGID_RSA; // TODO(wtc): hardcoded.
-
- memset(&public_key_, 0, sizeof(public_key_));
- public_key_.KeyData.Data = const_cast<uint8*>(&public_key_info_[0]);
- public_key_.KeyData.Length = public_key_info_.size();
- public_key_.KeyHeader.HeaderVersion = CSSM_KEYHEADER_VERSION;
- public_key_.KeyHeader.BlobType = CSSM_KEYBLOB_RAW;
- public_key_.KeyHeader.Format = CSSM_KEYBLOB_RAW_FORMAT_X509;
- public_key_.KeyHeader.AlgorithmId = key_alg;
- public_key_.KeyHeader.KeyClass = CSSM_KEYCLASS_PUBLIC_KEY;
- public_key_.KeyHeader.KeyAttr = CSSM_KEYATTR_EXTRACTABLE;
- public_key_.KeyHeader.KeyUsage = CSSM_KEYUSE_VERIFY;
- CSSM_KEY_SIZE key_size;
- CSSM_RETURN crtn;
- crtn = CSSM_QueryKeySizeInBits(GetSharedCSPHandle(), NULL,
- &public_key_, &key_size);
- if (crtn) {
- NOTREACHED() << "CSSM_QueryKeySizeInBits failed: " << crtn;
- return false;
- }
- public_key_.KeyHeader.LogicalKeySizeInBits = key_size.LogicalKeySizeInBits;
-
- // TODO(wtc): decode signature_algorithm...
- CSSM_ALGORITHMS sig_alg = CSSM_ALGID_SHA1WithRSA;
-
- crtn = CSSM_CSP_CreateSignatureContext(GetSharedCSPHandle(), sig_alg, NULL,
- &public_key_, &sig_handle_);
- if (crtn) {
- NOTREACHED();
- return false;
- }
- crtn = CSSM_VerifyDataInit(sig_handle_);
- if (crtn) {
- NOTREACHED();
- return false;
- }
- return true;
-}
-
-void SignatureVerifier::VerifyUpdate(const uint8* data_part,
- int data_part_len) {
- CSSM_DATA data;
- data.Data = const_cast<uint8*>(data_part);
- data.Length = data_part_len;
- CSSM_RETURN crtn = CSSM_VerifyDataUpdate(sig_handle_, &data, 1);
- DCHECK(crtn == CSSM_OK);
-}
-
-bool SignatureVerifier::VerifyFinal() {
- CSSM_DATA sig;
- sig.Data = const_cast<uint8*>(&signature_[0]);
- sig.Length = signature_.size();
- CSSM_RETURN crtn = CSSM_VerifyDataFinal(sig_handle_, &sig);
- Reset();
-
- // crtn is CSSMERR_CSP_VERIFY_FAILED if signature verification fails.
- return (crtn == CSSM_OK);
-}
-
-void SignatureVerifier::Reset() {
- CSSM_RETURN crtn;
- if (sig_handle_) {
- crtn = CSSM_DeleteContext(sig_handle_);
- DCHECK(crtn == CSSM_OK);
- sig_handle_ = 0;
- }
- signature_.clear();
-
- // Can't call CSSM_FreeKey on public_key_ because we constructed
- // public_key_ manually.
-}
-
-} // namespace base
-
diff --git a/base/crypto/signature_verifier_nss.cc b/base/crypto/signature_verifier_nss.cc
deleted file mode 100644
index 369f275..0000000
--- a/base/crypto/signature_verifier_nss.cc
+++ /dev/null
@@ -1,113 +0,0 @@
-// Copyright (c) 2009 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.
-
-#include "base/crypto/signature_verifier.h"
-
-#include <cryptohi.h>
-#include <keyhi.h>
-#include <stdlib.h>
-
-#include "base/logging.h"
-#include "base/nss_util.h"
-
-namespace base {
-
-SignatureVerifier::SignatureVerifier() : vfy_context_(NULL) {
- EnsureNSSInit();
-}
-
-SignatureVerifier::~SignatureVerifier() {
- Reset();
-}
-
-bool SignatureVerifier::VerifyInit(const uint8* signature_algorithm,
- int signature_algorithm_len,
- const uint8* signature,
- int signature_len,
- const uint8* public_key_info,
- int public_key_info_len) {
- signature_.assign(signature, signature + signature_len);
-
- CERTSubjectPublicKeyInfo* spki = NULL;
- SECItem spki_der;
- spki_der.type = siBuffer;
- spki_der.data = const_cast<uint8*>(public_key_info);
- spki_der.len = public_key_info_len;
- spki = SECKEY_DecodeDERSubjectPublicKeyInfo(&spki_der);
- if (!spki)
- return false;
- SECKEYPublicKey* public_key = SECKEY_ExtractPublicKey(spki);
- SECKEY_DestroySubjectPublicKeyInfo(spki); // Done with spki.
- if (!public_key)
- return false;
-
- PLArenaPool* arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (!arena) {
- SECKEY_DestroyPublicKey(public_key);
- return false;
- }
-
- SECItem sig_alg_der;
- sig_alg_der.type = siBuffer;
- sig_alg_der.data = const_cast<uint8*>(signature_algorithm);
- sig_alg_der.len = signature_algorithm_len;
- SECAlgorithmID sig_alg_id;
- SECStatus rv;
- rv = SEC_QuickDERDecodeItem(arena, &sig_alg_id, SECOID_AlgorithmIDTemplate,
- &sig_alg_der);
- if (rv != SECSuccess) {
- SECKEY_DestroyPublicKey(public_key);
- PORT_FreeArena(arena, PR_TRUE);
- return false;
- }
-
- SECItem sig;
- sig.type = siBuffer;
- sig.data = const_cast<uint8*>(signature);
- sig.len = signature_len;
- SECOidTag hash_alg_tag;
- vfy_context_ = VFY_CreateContextWithAlgorithmID(public_key, &sig,
- &sig_alg_id, &hash_alg_tag,
- NULL);
- SECKEY_DestroyPublicKey(public_key); // Done with public_key.
- PORT_FreeArena(arena, PR_TRUE); // Done with sig_alg_id.
- if (!vfy_context_) {
- // A corrupted RSA signature could be detected without the data, so
- // VFY_CreateContextWithAlgorithmID may fail with SEC_ERROR_BAD_SIGNATURE
- // (-8182).
- return false;
- }
-
- rv = VFY_Begin(vfy_context_);
- if (rv != SECSuccess) {
- NOTREACHED();
- return false;
- }
- return true;
-}
-
-void SignatureVerifier::VerifyUpdate(const uint8* data_part,
- int data_part_len) {
- SECStatus rv = VFY_Update(vfy_context_, data_part, data_part_len);
- DCHECK(rv == SECSuccess);
-}
-
-bool SignatureVerifier::VerifyFinal() {
- SECStatus rv = VFY_End(vfy_context_);
- Reset();
-
- // If signature verification fails, the error code is
- // SEC_ERROR_BAD_SIGNATURE (-8182).
- return (rv == SECSuccess);
-}
-
-void SignatureVerifier::Reset() {
- if (vfy_context_) {
- VFY_DestroyContext(vfy_context_, PR_TRUE);
- vfy_context_ = NULL;
- }
- signature_.clear();
-}
-
-} // namespace base
diff --git a/base/crypto/signature_verifier_openssl.cc b/base/crypto/signature_verifier_openssl.cc
deleted file mode 100644
index 4850efa..0000000
--- a/base/crypto/signature_verifier_openssl.cc
+++ /dev/null
@@ -1,94 +0,0 @@
-// 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.
-
-#include "base/crypto/signature_verifier.h"
-
-#include <openssl/evp.h>
-#include <openssl/x509.h>
-
-#include <vector>
-
-#include "base/logging.h"
-#include "base/openssl_util.h"
-#include "base/scoped_ptr.h"
-#include "base/stl_util-inl.h"
-
-namespace base {
-
-struct SignatureVerifier::VerifyContext {
- ScopedOpenSSL<EVP_PKEY, EVP_PKEY_free> public_key;
- ScopedOpenSSL<EVP_MD_CTX, EVP_MD_CTX_destroy> ctx;
-};
-
-SignatureVerifier::SignatureVerifier()
- : verify_context_(NULL) {
-}
-
-SignatureVerifier::~SignatureVerifier() {
- Reset();
-}
-
-bool SignatureVerifier::VerifyInit(const uint8* signature_algorithm,
- int signature_algorithm_len,
- const uint8* signature,
- int signature_len,
- const uint8* public_key_info,
- int public_key_info_len) {
- DCHECK(!verify_context_);
- verify_context_ = new VerifyContext;
- OpenSSLErrStackTracer err_tracer(FROM_HERE);
-
- ScopedOpenSSL<X509_ALGOR, X509_ALGOR_free> algorithm(
- d2i_X509_ALGOR(NULL, &signature_algorithm, signature_algorithm_len));
- if (!algorithm.get())
- return false;
-
- const EVP_MD* digest = EVP_get_digestbyobj(algorithm.get()->algorithm);
- DCHECK(digest);
-
- signature_.assign(signature, signature + signature_len);
-
- // BIO_new_mem_buf is not const aware, but it does not modify the buffer.
- char* data = reinterpret_cast<char*>(const_cast<uint8*>(public_key_info));
- ScopedOpenSSL<BIO, BIO_free_all> bio(BIO_new_mem_buf(data,
- public_key_info_len));
- if (!bio.get())
- return false;
-
- verify_context_->public_key.reset(d2i_PUBKEY_bio(bio.get(), NULL));
- if (!verify_context_->public_key.get())
- return false;
-
- verify_context_->ctx.reset(EVP_MD_CTX_create());
- int rv = EVP_VerifyInit_ex(verify_context_->ctx.get(), digest, NULL);
- return rv == 1;
-}
-
-void SignatureVerifier::VerifyUpdate(const uint8* data_part,
- int data_part_len) {
- DCHECK(verify_context_);
- OpenSSLErrStackTracer err_tracer(FROM_HERE);
- int rv = EVP_VerifyUpdate(verify_context_->ctx.get(),
- data_part, data_part_len);
- DCHECK_EQ(rv, 1);
-}
-
-bool SignatureVerifier::VerifyFinal() {
- DCHECK(verify_context_);
- OpenSSLErrStackTracer err_tracer(FROM_HERE);
- int rv = EVP_VerifyFinal(verify_context_->ctx.get(),
- vector_as_array(&signature_), signature_.size(),
- verify_context_->public_key.get());
- DCHECK_GE(rv, 0);
- Reset();
- return rv == 1;
-}
-
-void SignatureVerifier::Reset() {
- delete verify_context_;
- verify_context_ = NULL;
- signature_.clear();
-}
-
-} // namespace base
diff --git a/base/crypto/signature_verifier_unittest.cc b/base/crypto/signature_verifier_unittest.cc
deleted file mode 100644
index e28395f..0000000
--- a/base/crypto/signature_verifier_unittest.cc
+++ /dev/null
@@ -1,268 +0,0 @@
-// Copyright (c) 2009 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.
-
-#include "base/crypto/signature_verifier.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-TEST(SignatureVerifierTest, BasicTest) {
- // The input data in this test comes from real certificates.
- //
- // tbs_certificate ("to-be-signed certificate", the part of a certificate
- // that is signed), signature_algorithm, and algorithm come from the
- // certificate of bugs.webkit.org.
- //
- // public_key_info comes from the certificate of the issuer, Go Daddy Secure
- // Certification Authority.
- //
- // The bytes in the array initializers are formatted to expose the DER
- // encoding of the ASN.1 structures.
-
- // The data that is signed is the following ASN.1 structure:
- // TBSCertificate ::= SEQUENCE {
- // ... -- omitted, not important
- // }
- const uint8 tbs_certificate[1017] = {
- 0x30, 0x82, 0x03, 0xf5, // a SEQUENCE of length 1013 (0x3f5)
- 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x03, 0x43, 0xdd, 0x63, 0x30, 0x0d,
- 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05,
- 0x00, 0x30, 0x81, 0xca, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04,
- 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55,
- 0x04, 0x08, 0x13, 0x07, 0x41, 0x72, 0x69, 0x7a, 0x6f, 0x6e, 0x61, 0x31,
- 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0a, 0x53, 0x63,
- 0x6f, 0x74, 0x74, 0x73, 0x64, 0x61, 0x6c, 0x65, 0x31, 0x1a, 0x30, 0x18,
- 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x11, 0x47, 0x6f, 0x44, 0x61, 0x64,
- 0x64, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
- 0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2a, 0x68,
- 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66,
- 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x2e, 0x67, 0x6f, 0x64, 0x61, 0x64,
- 0x64, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73,
- 0x69, 0x74, 0x6f, 0x72, 0x79, 0x31, 0x30, 0x30, 0x2e, 0x06, 0x03, 0x55,
- 0x04, 0x03, 0x13, 0x27, 0x47, 0x6f, 0x20, 0x44, 0x61, 0x64, 0x64, 0x79,
- 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74,
- 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75,
- 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x11, 0x30, 0x0f, 0x06,
- 0x03, 0x55, 0x04, 0x05, 0x13, 0x08, 0x30, 0x37, 0x39, 0x36, 0x39, 0x32,
- 0x38, 0x37, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x38, 0x30, 0x33, 0x31, 0x38,
- 0x32, 0x33, 0x33, 0x35, 0x31, 0x39, 0x5a, 0x17, 0x0d, 0x31, 0x31, 0x30,
- 0x33, 0x31, 0x38, 0x32, 0x33, 0x33, 0x35, 0x31, 0x39, 0x5a, 0x30, 0x79,
- 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55,
- 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a,
- 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, 0x12,
- 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x09, 0x43, 0x75, 0x70,
- 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03,
- 0x55, 0x04, 0x0a, 0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49,
- 0x6e, 0x63, 0x2e, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0b,
- 0x13, 0x0c, 0x4d, 0x61, 0x63, 0x20, 0x4f, 0x53, 0x20, 0x46, 0x6f, 0x72,
- 0x67, 0x65, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
- 0x0c, 0x2a, 0x2e, 0x77, 0x65, 0x62, 0x6b, 0x69, 0x74, 0x2e, 0x6f, 0x72,
- 0x67, 0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
- 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30,
- 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xa7, 0x62, 0x79, 0x41, 0xda, 0x28,
- 0xf2, 0xc0, 0x4f, 0xe0, 0x25, 0xaa, 0xa1, 0x2e, 0x3b, 0x30, 0x94, 0xb5,
- 0xc9, 0x26, 0x3a, 0x1b, 0xe2, 0xd0, 0xcc, 0xa2, 0x95, 0xe2, 0x91, 0xc0,
- 0xf0, 0x40, 0x9e, 0x27, 0x6e, 0xbd, 0x6e, 0xde, 0x7c, 0xb6, 0x30, 0x5c,
- 0xb8, 0x9b, 0x01, 0x2f, 0x92, 0x04, 0xa1, 0xef, 0x4a, 0xb1, 0x6c, 0xb1,
- 0x7e, 0x8e, 0xcd, 0xa6, 0xf4, 0x40, 0x73, 0x1f, 0x2c, 0x96, 0xad, 0xff,
- 0x2a, 0x6d, 0x0e, 0xba, 0x52, 0x84, 0x83, 0xb0, 0x39, 0xee, 0xc9, 0x39,
- 0xdc, 0x1e, 0x34, 0xd0, 0xd8, 0x5d, 0x7a, 0x09, 0xac, 0xa9, 0xee, 0xca,
- 0x65, 0xf6, 0x85, 0x3a, 0x6b, 0xee, 0xe4, 0x5c, 0x5e, 0xf8, 0xda, 0xd1,
- 0xce, 0x88, 0x47, 0xcd, 0x06, 0x21, 0xe0, 0xb9, 0x4b, 0xe4, 0x07, 0xcb,
- 0x57, 0xdc, 0xca, 0x99, 0x54, 0xf7, 0x0e, 0xd5, 0x17, 0x95, 0x05, 0x2e,
- 0xe9, 0xb1, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0xce, 0x30,
- 0x82, 0x01, 0xca, 0x30, 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02,
- 0x30, 0x00, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03,
- 0x02, 0x05, 0xa0, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x16,
- 0x30, 0x14, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01,
- 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x30, 0x57,
- 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x50, 0x30, 0x4e, 0x30, 0x4c, 0xa0,
- 0x4a, 0xa0, 0x48, 0x86, 0x46, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f,
- 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73,
- 0x2e, 0x67, 0x6f, 0x64, 0x61, 0x64, 0x64, 0x79, 0x2e, 0x63, 0x6f, 0x6d,
- 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f,
- 0x67, 0x6f, 0x64, 0x61, 0x64, 0x64, 0x79, 0x65, 0x78, 0x74, 0x65, 0x6e,
- 0x64, 0x65, 0x64, 0x69, 0x73, 0x73, 0x75, 0x69, 0x6e, 0x67, 0x33, 0x2e,
- 0x63, 0x72, 0x6c, 0x30, 0x52, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x4b,
- 0x30, 0x49, 0x30, 0x47, 0x06, 0x0b, 0x60, 0x86, 0x48, 0x01, 0x86, 0xfd,
- 0x6d, 0x01, 0x07, 0x17, 0x02, 0x30, 0x38, 0x30, 0x36, 0x06, 0x08, 0x2b,
- 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x2a, 0x68, 0x74, 0x74,
- 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
- 0x61, 0x74, 0x65, 0x73, 0x2e, 0x67, 0x6f, 0x64, 0x61, 0x64, 0x64, 0x79,
- 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74,
- 0x6f, 0x72, 0x79, 0x30, 0x7f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
- 0x07, 0x01, 0x01, 0x04, 0x73, 0x30, 0x71, 0x30, 0x23, 0x06, 0x08, 0x2b,
- 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x17, 0x68, 0x74, 0x74,
- 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x67, 0x6f, 0x64,
- 0x61, 0x64, 0x64, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x4a, 0x06, 0x08,
- 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x3e, 0x68, 0x74,
- 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
- 0x63, 0x61, 0x74, 0x65, 0x73, 0x2e, 0x67, 0x6f, 0x64, 0x61, 0x64, 0x64,
- 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69,
- 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x67, 0x64, 0x5f, 0x69, 0x6e, 0x74, 0x65,
- 0x72, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x2e, 0x63, 0x72, 0x74,
- 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x48,
- 0xdf, 0x60, 0x32, 0xcc, 0x89, 0x01, 0xb6, 0xdc, 0x2f, 0xe3, 0x73, 0xb5,
- 0x9c, 0x16, 0x58, 0x32, 0x68, 0xa9, 0xc3, 0x30, 0x1f, 0x06, 0x03, 0x55,
- 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xfd, 0xac, 0x61, 0x32,
- 0x93, 0x6c, 0x45, 0xd6, 0xe2, 0xee, 0x85, 0x5f, 0x9a, 0xba, 0xe7, 0x76,
- 0x99, 0x68, 0xcc, 0xe7, 0x30, 0x23, 0x06, 0x03, 0x55, 0x1d, 0x11, 0x04,
- 0x1c, 0x30, 0x1a, 0x82, 0x0c, 0x2a, 0x2e, 0x77, 0x65, 0x62, 0x6b, 0x69,
- 0x74, 0x2e, 0x6f, 0x72, 0x67, 0x82, 0x0a, 0x77, 0x65, 0x62, 0x6b, 0x69,
- 0x74, 0x2e, 0x6f, 0x72, 0x67
- };
-
- // The signature algorithm is specified as the following ASN.1 structure:
- // AlgorithmIdentifier ::= SEQUENCE {
- // algorithm OBJECT IDENTIFIER,
- // parameters ANY DEFINED BY algorithm OPTIONAL }
- //
- const uint8 signature_algorithm[15] = {
- 0x30, 0x0d, // a SEQUENCE of length 13 (0xd)
- 0x06, 0x09, // an OBJECT IDENTIFIER of length 9
- // 1.2.840.113549.1.1.5 - sha1WithRSAEncryption
- 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05,
- 0x05, 0x00, // a NULL of length 0
- };
-
- // RSA signature, a big integer in the big-endian byte order.
- const uint8 signature[256] = {
- 0x1e, 0x6a, 0xe7, 0xe0, 0x4f, 0xe7, 0x4d, 0xd0, 0x69, 0x7c, 0xf8, 0x8f,
- 0x99, 0xb4, 0x18, 0x95, 0x36, 0x24, 0x0f, 0x0e, 0xa3, 0xea, 0x34, 0x37,
- 0xf4, 0x7d, 0xd5, 0x92, 0x35, 0x53, 0x72, 0x76, 0x3f, 0x69, 0xf0, 0x82,
- 0x56, 0xe3, 0x94, 0x7a, 0x1d, 0x1a, 0x81, 0xaf, 0x9f, 0xc7, 0x43, 0x01,
- 0x64, 0xd3, 0x7c, 0x0d, 0xc8, 0x11, 0x4e, 0x4a, 0xe6, 0x1a, 0xc3, 0x01,
- 0x74, 0xe8, 0x35, 0x87, 0x5c, 0x61, 0xaa, 0x8a, 0x46, 0x06, 0xbe, 0x98,
- 0x95, 0x24, 0x9e, 0x01, 0xe3, 0xe6, 0xa0, 0x98, 0xee, 0x36, 0x44, 0x56,
- 0x8d, 0x23, 0x9c, 0x65, 0xea, 0x55, 0x6a, 0xdf, 0x66, 0xee, 0x45, 0xe8,
- 0xa0, 0xe9, 0x7d, 0x9a, 0xba, 0x94, 0xc5, 0xc8, 0xc4, 0x4b, 0x98, 0xff,
- 0x9a, 0x01, 0x31, 0x6d, 0xf9, 0x2b, 0x58, 0xe7, 0xe7, 0x2a, 0xc5, 0x4d,
- 0xbb, 0xbb, 0xcd, 0x0d, 0x70, 0xe1, 0xad, 0x03, 0xf5, 0xfe, 0xf4, 0x84,
- 0x71, 0x08, 0xd2, 0xbc, 0x04, 0x7b, 0x26, 0x1c, 0xa8, 0x0f, 0x9c, 0xd8,
- 0x12, 0x6a, 0x6f, 0x2b, 0x67, 0xa1, 0x03, 0x80, 0x9a, 0x11, 0x0b, 0xe9,
- 0xe0, 0xb5, 0xb3, 0xb8, 0x19, 0x4e, 0x0c, 0xa4, 0xd9, 0x2b, 0x3b, 0xc2,
- 0xca, 0x20, 0xd3, 0x0c, 0xa4, 0xff, 0x93, 0x13, 0x1f, 0xfc, 0xba, 0x94,
- 0x93, 0x8c, 0x64, 0x15, 0x2e, 0x28, 0xa9, 0x55, 0x8c, 0x2c, 0x48, 0xd3,
- 0xd3, 0xc1, 0x50, 0x69, 0x19, 0xe8, 0x34, 0xd3, 0xf1, 0x04, 0x9f, 0x0a,
- 0x7a, 0x21, 0x87, 0xbf, 0xb9, 0x59, 0x37, 0x2e, 0xf4, 0x71, 0xa5, 0x3e,
- 0xbe, 0xcd, 0x70, 0x83, 0x18, 0xf8, 0x8a, 0x72, 0x85, 0x45, 0x1f, 0x08,
- 0x01, 0x6f, 0x37, 0xf5, 0x2b, 0x7b, 0xea, 0xb9, 0x8b, 0xa3, 0xcc, 0xfd,
- 0x35, 0x52, 0xdd, 0x66, 0xde, 0x4f, 0x30, 0xc5, 0x73, 0x81, 0xb6, 0xe8,
- 0x3c, 0xd8, 0x48, 0x8a
- };
-
- // The public key is specified as the following ASN.1 structure:
- // SubjectPublicKeyInfo ::= SEQUENCE {
- // algorithm AlgorithmIdentifier,
- // subjectPublicKey BIT STRING }
- const uint8 public_key_info[294] = {
- 0x30, 0x82, 0x01, 0x22, // a SEQUENCE of length 290 (0x122)
- // algorithm
- 0x30, 0x0d, // a SEQUENCE of length 13
- 0x06, 0x09, // an OBJECT IDENTIFIER of length 9
- 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01,
- 0x05, 0x00, // a NULL of length 0
- // subjectPublicKey
- 0x03, 0x82, 0x01, 0x0f, // a BIT STRING of length 271 (0x10f)
- 0x00, // number of unused bits
- 0x30, 0x82, 0x01, 0x0a, // a SEQUENCE of length 266 (0x10a)
- // modulus
- 0x02, 0x82, 0x01, 0x01, // an INTEGER of length 257 (0x101)
- 0x00, 0xc4, 0x2d, 0xd5, 0x15, 0x8c, 0x9c, 0x26, 0x4c, 0xec,
- 0x32, 0x35, 0xeb, 0x5f, 0xb8, 0x59, 0x01, 0x5a, 0xa6, 0x61,
- 0x81, 0x59, 0x3b, 0x70, 0x63, 0xab, 0xe3, 0xdc, 0x3d, 0xc7,
- 0x2a, 0xb8, 0xc9, 0x33, 0xd3, 0x79, 0xe4, 0x3a, 0xed, 0x3c,
- 0x30, 0x23, 0x84, 0x8e, 0xb3, 0x30, 0x14, 0xb6, 0xb2, 0x87,
- 0xc3, 0x3d, 0x95, 0x54, 0x04, 0x9e, 0xdf, 0x99, 0xdd, 0x0b,
- 0x25, 0x1e, 0x21, 0xde, 0x65, 0x29, 0x7e, 0x35, 0xa8, 0xa9,
- 0x54, 0xeb, 0xf6, 0xf7, 0x32, 0x39, 0xd4, 0x26, 0x55, 0x95,
- 0xad, 0xef, 0xfb, 0xfe, 0x58, 0x86, 0xd7, 0x9e, 0xf4, 0x00,
- 0x8d, 0x8c, 0x2a, 0x0c, 0xbd, 0x42, 0x04, 0xce, 0xa7, 0x3f,
- 0x04, 0xf6, 0xee, 0x80, 0xf2, 0xaa, 0xef, 0x52, 0xa1, 0x69,
- 0x66, 0xda, 0xbe, 0x1a, 0xad, 0x5d, 0xda, 0x2c, 0x66, 0xea,
- 0x1a, 0x6b, 0xbb, 0xe5, 0x1a, 0x51, 0x4a, 0x00, 0x2f, 0x48,
- 0xc7, 0x98, 0x75, 0xd8, 0xb9, 0x29, 0xc8, 0xee, 0xf8, 0x66,
- 0x6d, 0x0a, 0x9c, 0xb3, 0xf3, 0xfc, 0x78, 0x7c, 0xa2, 0xf8,
- 0xa3, 0xf2, 0xb5, 0xc3, 0xf3, 0xb9, 0x7a, 0x91, 0xc1, 0xa7,
- 0xe6, 0x25, 0x2e, 0x9c, 0xa8, 0xed, 0x12, 0x65, 0x6e, 0x6a,
- 0xf6, 0x12, 0x44, 0x53, 0x70, 0x30, 0x95, 0xc3, 0x9c, 0x2b,
- 0x58, 0x2b, 0x3d, 0x08, 0x74, 0x4a, 0xf2, 0xbe, 0x51, 0xb0,
- 0xbf, 0x87, 0xd0, 0x4c, 0x27, 0x58, 0x6b, 0xb5, 0x35, 0xc5,
- 0x9d, 0xaf, 0x17, 0x31, 0xf8, 0x0b, 0x8f, 0xee, 0xad, 0x81,
- 0x36, 0x05, 0x89, 0x08, 0x98, 0xcf, 0x3a, 0xaf, 0x25, 0x87,
- 0xc0, 0x49, 0xea, 0xa7, 0xfd, 0x67, 0xf7, 0x45, 0x8e, 0x97,
- 0xcc, 0x14, 0x39, 0xe2, 0x36, 0x85, 0xb5, 0x7e, 0x1a, 0x37,
- 0xfd, 0x16, 0xf6, 0x71, 0x11, 0x9a, 0x74, 0x30, 0x16, 0xfe,
- 0x13, 0x94, 0xa3, 0x3f, 0x84, 0x0d, 0x4f,
- // public exponent
- 0x02, 0x03, // an INTEGER of length 3
- 0x01, 0x00, 0x01
- };
-
- // We use the signature verifier to perform four signature verification
- // tests.
- base::SignatureVerifier verifier;
- bool ok;
-
- // Test 1: feed all of the data to the verifier at once (a single
- // VerifyUpdate call).
- ok = verifier.VerifyInit(signature_algorithm,
- sizeof(signature_algorithm),
- signature, sizeof(signature),
- public_key_info, sizeof(public_key_info));
- EXPECT_TRUE(ok);
- verifier.VerifyUpdate(tbs_certificate, sizeof(tbs_certificate));
- ok = verifier.VerifyFinal();
- EXPECT_TRUE(ok);
-
- // Test 2: feed the data to the verifier in three parts (three VerifyUpdate
- // calls).
- ok = verifier.VerifyInit(signature_algorithm,
- sizeof(signature_algorithm),
- signature, sizeof(signature),
- public_key_info, sizeof(public_key_info));
- EXPECT_TRUE(ok);
- verifier.VerifyUpdate(tbs_certificate, 256);
- verifier.VerifyUpdate(tbs_certificate + 256, 256);
- verifier.VerifyUpdate(tbs_certificate + 512, sizeof(tbs_certificate) - 512);
- ok = verifier.VerifyFinal();
- EXPECT_TRUE(ok);
-
- // Test 3: verify the signature with incorrect data.
- uint8 bad_tbs_certificate[sizeof(tbs_certificate)];
- memcpy(bad_tbs_certificate, tbs_certificate, sizeof(tbs_certificate));
- bad_tbs_certificate[10] += 1; // Corrupt one byte of the data.
- ok = verifier.VerifyInit(signature_algorithm,
- sizeof(signature_algorithm),
- signature, sizeof(signature),
- public_key_info, sizeof(public_key_info));
- EXPECT_TRUE(ok);
- verifier.VerifyUpdate(bad_tbs_certificate, sizeof(bad_tbs_certificate));
- ok = verifier.VerifyFinal();
-
- // Purify disables digital signature verification, causing the Windows
- // CryptoAPI function CryptVerifySignature to always succeed. So we can't
- // check the signature verification results of the negative tests when
- // running inside Purify. See http://crbug.com/10031.
-#ifndef PURIFY
- EXPECT_FALSE(ok);
-#endif
-
- // Test 4: verify a bad signature.
- uint8 bad_signature[sizeof(signature)];
- memcpy(bad_signature, signature, sizeof(signature));
- bad_signature[10] += 1; // Corrupt one byte of the signature.
- ok = verifier.VerifyInit(signature_algorithm,
- sizeof(signature_algorithm),
- bad_signature, sizeof(bad_signature),
- public_key_info, sizeof(public_key_info));
-
- // A crypto library (e.g., NSS) may detect that the signature is corrupted
- // and cause VerifyInit to return false, so it is fine for 'ok' to be false.
- if (ok) {
- verifier.VerifyUpdate(tbs_certificate, sizeof(tbs_certificate));
- ok = verifier.VerifyFinal();
-#ifndef PURIFY
- EXPECT_FALSE(ok);
-#endif
- }
-}
diff --git a/base/crypto/signature_verifier_win.cc b/base/crypto/signature_verifier_win.cc
deleted file mode 100644
index c040d05..0000000
--- a/base/crypto/signature_verifier_win.cc
+++ /dev/null
@@ -1,134 +0,0 @@
-// Copyright (c) 2009 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.
-
-#include "base/crypto/signature_verifier.h"
-
-#include "base/logging.h"
-
-#pragma comment(lib, "crypt32.lib")
-
-namespace {
-
-// Wrappers of malloc and free for CRYPT_DECODE_PARA, which requires the
-// WINAPI calling convention.
-void* WINAPI MyCryptAlloc(size_t size) {
- return malloc(size);
-}
-
-void WINAPI MyCryptFree(void* p) {
- free(p);
-}
-
-} // namespace
-
-namespace base {
-
-SignatureVerifier::SignatureVerifier() : hash_object_(0), public_key_(0) {
- if (!CryptAcquireContext(provider_.receive(), NULL, NULL,
- PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
- provider_.reset();
-}
-
-SignatureVerifier::~SignatureVerifier() {
-}
-
-bool SignatureVerifier::VerifyInit(const uint8* signature_algorithm,
- int signature_algorithm_len,
- const uint8* signature,
- int signature_len,
- const uint8* public_key_info,
- int public_key_info_len) {
- signature_.reserve(signature_len);
- // CryptoAPI uses big integers in the little-endian byte order, so we need
- // to first swap the order of signature bytes.
- for (int i = signature_len - 1; i >= 0; --i)
- signature_.push_back(signature[i]);
-
- CRYPT_DECODE_PARA decode_para;
- decode_para.cbSize = sizeof(decode_para);
- decode_para.pfnAlloc = MyCryptAlloc;
- decode_para.pfnFree = MyCryptFree;
- CERT_PUBLIC_KEY_INFO* cert_public_key_info = NULL;
- DWORD struct_len = 0;
- BOOL ok;
- ok = CryptDecodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
- X509_PUBLIC_KEY_INFO,
- public_key_info,
- public_key_info_len,
- CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_NOCOPY_FLAG,
- &decode_para,
- &cert_public_key_info,
- &struct_len);
- if (!ok)
- return false;
-
- ok = CryptImportPublicKeyInfo(provider_,
- X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
- cert_public_key_info, public_key_.receive());
- free(cert_public_key_info);
- if (!ok)
- return false;
-
- CRYPT_ALGORITHM_IDENTIFIER* signature_algorithm_id;
- struct_len = 0;
- ok = CryptDecodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
- X509_ALGORITHM_IDENTIFIER,
- signature_algorithm,
- signature_algorithm_len,
- CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_NOCOPY_FLAG,
- &decode_para,
- &signature_algorithm_id,
- &struct_len);
- DCHECK(ok || GetLastError() == ERROR_FILE_NOT_FOUND);
- ALG_ID hash_alg_id;
- if (ok) {
- hash_alg_id = CALG_MD4; // Initialize to a weak hash algorithm that we
- // don't support.
- if (!strcmp(signature_algorithm_id->pszObjId, szOID_RSA_SHA1RSA))
- hash_alg_id = CALG_SHA1;
- else if (!strcmp(signature_algorithm_id->pszObjId, szOID_RSA_MD5RSA))
- hash_alg_id = CALG_MD5;
- free(signature_algorithm_id);
- DCHECK(hash_alg_id != CALG_MD4);
- if (hash_alg_id == CALG_MD4)
- return false; // Unsupported hash algorithm.
- } else if (GetLastError() == ERROR_FILE_NOT_FOUND) {
- // TODO(wtc): X509_ALGORITHM_IDENTIFIER isn't supported on XP SP2. We
- // may be able to encapsulate signature_algorithm in a dummy SignedContent
- // and decode it with X509_CERT into a CERT_SIGNED_CONTENT_INFO. For now,
- // just hardcode the hash algorithm to be SHA-1.
- hash_alg_id = CALG_SHA1;
- } else {
- return false;
- }
-
- ok = CryptCreateHash(provider_, hash_alg_id, 0, 0, hash_object_.receive());
- if (!ok)
- return false;
- return true;
-}
-
-void SignatureVerifier::VerifyUpdate(const uint8* data_part,
- int data_part_len) {
- BOOL ok = CryptHashData(hash_object_, data_part, data_part_len, 0);
- DCHECK(ok) << "CryptHashData failed: " << GetLastError();
-}
-
-bool SignatureVerifier::VerifyFinal() {
- BOOL ok = CryptVerifySignature(hash_object_, &signature_[0],
- signature_.size(), public_key_, NULL, 0);
- Reset();
- if (!ok)
- return false;
- return true;
-}
-
-void SignatureVerifier::Reset() {
- hash_object_.reset();
- public_key_.reset();
- signature_.clear();
-}
-
-} // namespace base
-
diff --git a/base/crypto/symmetric_key.h b/base/crypto/symmetric_key.h
deleted file mode 100644
index ce98fa6..0000000
--- a/base/crypto/symmetric_key.h
+++ /dev/null
@@ -1,104 +0,0 @@
-// 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 BASE_CRYPTO_SYMMETRIC_KEY_H_
-#define BASE_CRYPTO_SYMMETRIC_KEY_H_
-#pragma once
-
-#include <string>
-
-#include "base/basictypes.h"
-
-#if defined(USE_NSS)
-#include "base/crypto/scoped_nss_types.h"
-#elif defined(OS_MACOSX)
-#include <Security/cssmtype.h>
-#elif defined(OS_WIN)
-#include "base/crypto/scoped_capi_types.h"
-#endif
-
-namespace base {
-
-// Wraps a platform-specific symmetric key and allows it to be held in a
-// scoped_ptr.
-class SymmetricKey {
- public:
- // Defines the algorithm that a key will be used with. See also
- // classs Encrptor.
- enum Algorithm {
- AES,
- HMAC_SHA1,
- };
-
- virtual ~SymmetricKey();
-
- // Generates a random key suitable to be used with |algorithm| and of
- // |key_size_in_bits| bits.
- // The caller is responsible for deleting the returned SymmetricKey.
- static SymmetricKey* GenerateRandomKey(Algorithm algorithm,
- size_t key_size_in_bits);
-
- // Derives a key from the supplied password and salt using PBKDF2, suitable
- // for use with specified |algorithm|. Note |algorithm| is not the algorithm
- // used to derive the key from the password. The caller is responsible for
- // deleting the returned SymmetricKey.
- static SymmetricKey* DeriveKeyFromPassword(Algorithm algorithm,
- const std::string& password,
- const std::string& salt,
- size_t iterations,
- size_t key_size_in_bits);
-
- // Imports an array of key bytes in |raw_key|. This key may have been
- // generated by GenerateRandomKey or DeriveKeyFromPassword and exported with
- // GetRawKey, or via another compatible method. The key must be of suitable
- // size for use with |algorithm|. The caller owns the returned SymmetricKey.
- static SymmetricKey* Import(Algorithm algorithm, const std::string& raw_key);
-
-#if defined(USE_OPENSSL)
- const std::string& key() { return key_; }
-#elif defined(USE_NSS)
- PK11SymKey* key() const { return key_.get(); }
-#elif defined(OS_MACOSX)
- CSSM_DATA cssm_data() const;
-#elif defined(OS_WIN)
- HCRYPTKEY key() const { return key_.get(); }
-#endif
-
- // Extracts the raw key from the platform specific data.
- // Warning: |raw_key| holds the raw key as bytes and thus must be handled
- // carefully.
- bool GetRawKey(std::string* raw_key);
-
- private:
-#if defined(USE_OPENSSL)
- SymmetricKey() {}
- std::string key_;
-#elif defined(USE_NSS)
- explicit SymmetricKey(PK11SymKey* key);
- ScopedPK11SymKey key_;
-#elif defined(OS_MACOSX)
- SymmetricKey(const void* key_data, size_t key_size_in_bits);
- std::string key_;
-#elif defined(OS_WIN)
- SymmetricKey(HCRYPTPROV provider, HCRYPTKEY key,
- const void* key_data, size_t key_size_in_bytes);
-
- ScopedHCRYPTPROV provider_;
- ScopedHCRYPTKEY key_;
-
- // Contains the raw key, if it is known during initialization and when it
- // is likely that the associated |provider_| will be unable to export the
- // |key_|. This is the case of HMAC keys when the key size exceeds 16 bytes
- // when using the default RSA provider.
- // TODO(rsleevi): See if KP_EFFECTIVE_KEYLEN is the reason why CryptExportKey
- // fails with NTE_BAD_KEY/NTE_BAD_LEN
- std::string raw_key_;
-#endif
-
- DISALLOW_COPY_AND_ASSIGN(SymmetricKey);
-};
-
-} // namespace base
-
-#endif // BASE_CRYPTO_SYMMETRIC_KEY_H_
diff --git a/base/crypto/symmetric_key_mac.cc b/base/crypto/symmetric_key_mac.cc
deleted file mode 100644
index 574f9d2..0000000
--- a/base/crypto/symmetric_key_mac.cc
+++ /dev/null
@@ -1,155 +0,0 @@
-// 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.
-
-#include "base/crypto/symmetric_key.h"
-
-#include <CommonCrypto/CommonCryptor.h>
-#include <CoreFoundation/CFString.h>
-#include <Security/cssm.h>
-
-#include "base/crypto/cssm_init.h"
-#include "base/logging.h"
-
-namespace {
-
-CSSM_KEY_TYPE CheckKeyParams(base::SymmetricKey::Algorithm algorithm,
- size_t key_size_in_bits) {
- if (algorithm == base::SymmetricKey::AES) {
- CHECK(key_size_in_bits == 128 ||
- key_size_in_bits == 192 ||
- key_size_in_bits == 256)
- << "Invalid key size " << key_size_in_bits << " bits";
- return CSSM_ALGID_AES;
- } else {
- // FIPS 198 Section 3 requires a HMAC-SHA-1 derived keys to be at least
- // (HMAC-SHA-1 output size / 2) to be compliant. Since the ouput size of
- // HMAC-SHA-1 is 160 bits, we require at least 80 bits here.
- CHECK(algorithm == base::SymmetricKey::HMAC_SHA1);
- CHECK(key_size_in_bits >= 80 && (key_size_in_bits % 8) == 0)
- << "Invalid key size " << key_size_in_bits << " bits";
- return CSSM_ALGID_SHA1HMAC_LEGACY;
- }
-}
-
-void* CreateRandomBytes(size_t size) {
- CSSM_RETURN err;
- CSSM_CC_HANDLE ctx;
- err = CSSM_CSP_CreateRandomGenContext(base::GetSharedCSPHandle(),
- CSSM_ALGID_APPLE_YARROW,
- NULL,
- size, &ctx);
- if (err) {
- base::LogCSSMError("CSSM_CSP_CreateRandomGenContext", err);
- return NULL;
- }
- CSSM_DATA random_data = {};
- err = CSSM_GenerateRandom(ctx, &random_data);
- if (err) {
- base::LogCSSMError("CSSM_GenerateRandom", err);
- random_data.Data = NULL;
- }
- CSSM_DeleteContext(ctx);
- return random_data.Data; // Caller responsible for freeing this
-}
-
-inline CSSM_DATA StringToData(const std::string& str) {
- CSSM_DATA data = {
- str.size(),
- reinterpret_cast<uint8_t*>(const_cast<char*>(str.data()))
- };
- return data;
-}
-
-} // namespace
-
-namespace base {
-
-SymmetricKey::~SymmetricKey() {}
-
-// static
-SymmetricKey* SymmetricKey::GenerateRandomKey(Algorithm algorithm,
- size_t key_size_in_bits) {
- CheckKeyParams(algorithm, key_size_in_bits);
- void* random_bytes = CreateRandomBytes((key_size_in_bits + 7) / 8);
- if (!random_bytes)
- return NULL;
- SymmetricKey *key = new SymmetricKey(random_bytes, key_size_in_bits);
- free(random_bytes);
- return key;
-}
-
-// static
-SymmetricKey* SymmetricKey::DeriveKeyFromPassword(Algorithm algorithm,
- const std::string& password,
- const std::string& salt,
- size_t iterations,
- size_t key_size_in_bits) {
- // Derived (haha) from cdsaDeriveKey() in Apple's CryptoSample.
- CSSM_KEY_TYPE key_type = CheckKeyParams(algorithm, key_size_in_bits);
- SymmetricKey* derived_key = NULL;
- CSSM_KEY cssm_key = {};
-
- CSSM_CC_HANDLE ctx = 0;
- CSSM_ACCESS_CREDENTIALS credentials = {};
- CSSM_RETURN err;
- CSSM_DATA salt_data = StringToData(salt);
- err = CSSM_CSP_CreateDeriveKeyContext(GetSharedCSPHandle(),
- CSSM_ALGID_PKCS5_PBKDF2,
- key_type, key_size_in_bits,
- &credentials,
- NULL,
- iterations,
- &salt_data,
- NULL,
- &ctx);
- if (err) {
- LogCSSMError("CSSM_CSP_CreateDeriveKeyContext", err);
- return NULL;
- }
-
- CSSM_PKCS5_PBKDF2_PARAMS params = {};
- params.Passphrase = StringToData(password);
- params.PseudoRandomFunction = CSSM_PKCS5_PBKDF2_PRF_HMAC_SHA1;
- CSSM_DATA param_data = {sizeof(params), reinterpret_cast<uint8_t*>(&params)};
- err = CSSM_DeriveKey(ctx,
- &param_data,
- CSSM_KEYUSE_ANY,
- CSSM_KEYATTR_RETURN_DATA | CSSM_KEYATTR_EXTRACTABLE,
- NULL,
- NULL,
- &cssm_key);
- if (err) {
- LogCSSMError("CSSM_DeriveKey", err);
- goto exit;
- }
-
- DCHECK_EQ(cssm_key.KeyData.Length, key_size_in_bits / 8);
- derived_key = new SymmetricKey(cssm_key.KeyData.Data, key_size_in_bits);
-
- exit:
- CSSM_DeleteContext(ctx);
- CSSM_FreeKey(GetSharedCSPHandle(), &credentials, &cssm_key, false);
- return derived_key;
-}
-
-// static
-SymmetricKey* SymmetricKey::Import(Algorithm algorithm,
- const std::string& raw_key) {
- return new SymmetricKey(raw_key.data(), raw_key.size() * 8);
-}
-
-SymmetricKey::SymmetricKey(const void *key_data, size_t key_size_in_bits)
- : key_(reinterpret_cast<const char*>(key_data),
- key_size_in_bits / 8) {}
-
-bool SymmetricKey::GetRawKey(std::string* raw_key) {
- *raw_key = key_;
- return true;
-}
-
-CSSM_DATA SymmetricKey::cssm_data() const {
- return StringToData(key_);
-}
-
-} // namespace base
diff --git a/base/crypto/symmetric_key_nss.cc b/base/crypto/symmetric_key_nss.cc
deleted file mode 100644
index 1e3551d..0000000
--- a/base/crypto/symmetric_key_nss.cc
+++ /dev/null
@@ -1,127 +0,0 @@
-// 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.
-
-#include "base/crypto/symmetric_key.h"
-
-#include <nss.h>
-#include <pk11pub.h>
-
-#include "base/nss_util.h"
-#include "base/logging.h"
-
-namespace base {
-
-SymmetricKey::~SymmetricKey() {}
-
-// static
-SymmetricKey* SymmetricKey::GenerateRandomKey(Algorithm algorithm,
- size_t key_size_in_bits) {
- DCHECK_EQ(AES, algorithm);
-
- EnsureNSSInit();
- if (key_size_in_bits == 0)
- return NULL;
-
- ScopedPK11Slot slot(PK11_GetBestSlot(CKM_AES_KEY_GEN, NULL));
- if (!slot.get())
- return NULL;
-
- PK11SymKey* sym_key = PK11_KeyGen(slot.get(), CKM_AES_KEY_GEN, NULL,
- key_size_in_bits / 8, NULL);
- if (!sym_key)
- return NULL;
-
- return new SymmetricKey(sym_key);
-}
-
-// static
-SymmetricKey* SymmetricKey::DeriveKeyFromPassword(Algorithm algorithm,
- const std::string& password,
- const std::string& salt,
- size_t iterations,
- size_t key_size_in_bits) {
- EnsureNSSInit();
- if (salt.empty() || iterations == 0 || key_size_in_bits == 0)
- return NULL;
-
- SECItem password_item;
- password_item.type = siBuffer;
- password_item.data = reinterpret_cast<unsigned char*>(
- const_cast<char *>(password.data()));
- password_item.len = password.size();
-
- SECItem salt_item;
- salt_item.type = siBuffer;
- salt_item.data = reinterpret_cast<unsigned char*>(
- const_cast<char *>(salt.data()));
- salt_item.len = salt.size();
-
- SECOidTag cipher_algorithm =
- algorithm == AES ? SEC_OID_AES_256_CBC : SEC_OID_HMAC_SHA1;
- ScopedSECAlgorithmID alg_id(PK11_CreatePBEV2AlgorithmID(SEC_OID_PKCS5_PBKDF2,
- cipher_algorithm,
- SEC_OID_HMAC_SHA1,
- key_size_in_bits / 8,
- iterations,
- &salt_item));
- if (!alg_id.get())
- return NULL;
-
- ScopedPK11Slot slot(PK11_GetBestSlot(SEC_OID_PKCS5_PBKDF2, NULL));
- if (!slot.get())
- return NULL;
-
- PK11SymKey* sym_key = PK11_PBEKeyGen(slot.get(), alg_id.get(), &password_item,
- PR_FALSE, NULL);
- if (!sym_key)
- return NULL;
-
- return new SymmetricKey(sym_key);
-}
-
-// static
-SymmetricKey* SymmetricKey::Import(Algorithm algorithm,
- const std::string& raw_key) {
- CK_MECHANISM_TYPE cipher =
- algorithm == AES ? CKM_AES_CBC : CKM_SHA_1_HMAC;
-
- SECItem key_item;
- key_item.type = siBuffer;
- key_item.data = reinterpret_cast<unsigned char*>(
- const_cast<char *>(raw_key.data()));
- key_item.len = raw_key.size();
-
- ScopedPK11Slot slot(PK11_GetBestSlot(cipher, NULL));
- if (!slot.get())
- return NULL;
-
- // The exact value of the |origin| argument doesn't matter to NSS as long as
- // it's not PK11_OriginFortezzaHack, so we pass PK11_OriginUnwrap as a
- // placeholder.
- PK11SymKey* sym_key = PK11_ImportSymKey(slot.get(), cipher, PK11_OriginUnwrap,
- CKA_ENCRYPT, &key_item, NULL);
- if (!sym_key)
- return NULL;
-
- return new SymmetricKey(sym_key);
-}
-
-bool SymmetricKey::GetRawKey(std::string* raw_key) {
- SECStatus rv = PK11_ExtractKeyValue(key_.get());
- if (SECSuccess != rv)
- return false;
-
- SECItem* key_item = PK11_GetKeyData(key_.get());
- if (!key_item)
- return false;
-
- raw_key->assign(reinterpret_cast<char*>(key_item->data), key_item->len);
- return true;
-}
-
-SymmetricKey::SymmetricKey(PK11SymKey* key) : key_(key) {
- DCHECK(key);
-}
-
-} // namespace base
diff --git a/base/crypto/symmetric_key_openssl.cc b/base/crypto/symmetric_key_openssl.cc
deleted file mode 100644
index 409cce4..0000000
--- a/base/crypto/symmetric_key_openssl.cc
+++ /dev/null
@@ -1,76 +0,0 @@
-// 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.
-
-#include "base/crypto/symmetric_key.h"
-
-#include <openssl/evp.h>
-#include <openssl/rand.h>
-
-#include <algorithm>
-
-#include "base/logging.h"
-#include "base/openssl_util.h"
-#include "base/scoped_ptr.h"
-#include "base/string_util.h"
-
-namespace base {
-
-SymmetricKey::~SymmetricKey() {
- std::fill(key_.begin(), key_.end(), '\0'); // Zero out the confidential key.
-}
-
-// static
-SymmetricKey* SymmetricKey::GenerateRandomKey(Algorithm algorithm,
- size_t key_size_in_bits) {
- DCHECK_EQ(AES, algorithm);
- int key_size_in_bytes = key_size_in_bits / 8;
- DCHECK_EQ(static_cast<int>(key_size_in_bits), key_size_in_bytes * 8);
-
- if (key_size_in_bits == 0)
- return NULL;
-
- OpenSSLErrStackTracer err_tracer(FROM_HERE);
- scoped_ptr<SymmetricKey> key(new SymmetricKey);
- uint8* key_data =
- reinterpret_cast<uint8*>(WriteInto(&key->key_, key_size_in_bytes + 1));
-
- int rv = RAND_bytes(key_data, key_size_in_bytes);
- return rv == 1 ? key.release() : NULL;
-}
-
-// static
-SymmetricKey* SymmetricKey::DeriveKeyFromPassword(Algorithm algorithm,
- const std::string& password,
- const std::string& salt,
- size_t iterations,
- size_t key_size_in_bits) {
- DCHECK(algorithm == AES || algorithm == HMAC_SHA1);
- int key_size_in_bytes = key_size_in_bits / 8;
- DCHECK_EQ(static_cast<int>(key_size_in_bits), key_size_in_bytes * 8);
-
- OpenSSLErrStackTracer err_tracer(FROM_HERE);
- scoped_ptr<SymmetricKey> key(new SymmetricKey);
- uint8* key_data =
- reinterpret_cast<uint8*>(WriteInto(&key->key_, key_size_in_bytes + 1));
- int rv = PKCS5_PBKDF2_HMAC_SHA1(password.data(), password.length(),
- reinterpret_cast<const uint8*>(salt.data()),
- salt.length(), iterations,
- key_size_in_bytes, key_data);
- return rv == 1 ? key.release() : NULL;
-}
-
-// static
-SymmetricKey* SymmetricKey::Import(Algorithm algorithm,
- const std::string& raw_key) {
- scoped_ptr<SymmetricKey> key(new SymmetricKey);
- key->key_ = raw_key;
- return key.release();
-}
-
-bool SymmetricKey::GetRawKey(std::string* raw_key) {
- *raw_key = key_;
- return true;
-}
-
-} // namespace base
diff --git a/base/crypto/symmetric_key_unittest.cc b/base/crypto/symmetric_key_unittest.cc
deleted file mode 100644
index a9b0b9e..0000000
--- a/base/crypto/symmetric_key_unittest.cc
+++ /dev/null
@@ -1,226 +0,0 @@
-// 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.
-
-#include "base/crypto/symmetric_key.h"
-
-#include <string>
-
-#include "base/scoped_ptr.h"
-#include "base/string_number_conversions.h"
-#include "base/string_util.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-TEST(SymmetricKeyTest, GenerateRandomKey) {
- scoped_ptr<base::SymmetricKey> key(
- base::SymmetricKey::GenerateRandomKey(base::SymmetricKey::AES, 256));
- ASSERT_TRUE(NULL != key.get());
- std::string raw_key;
- EXPECT_TRUE(key->GetRawKey(&raw_key));
- EXPECT_EQ(32U, raw_key.size());
-
- // Do it again and check that the keys are different.
- // (Note: this has a one-in-10^77 chance of failure!)
- scoped_ptr<base::SymmetricKey> key2(
- base::SymmetricKey::GenerateRandomKey(base::SymmetricKey::AES, 256));
- ASSERT_TRUE(NULL != key2.get());
- std::string raw_key2;
- EXPECT_TRUE(key2->GetRawKey(&raw_key2));
- EXPECT_EQ(32U, raw_key2.size());
- EXPECT_NE(raw_key, raw_key2);
-}
-
-TEST(SymmetricKeyTest, ImportGeneratedKey) {
- scoped_ptr<base::SymmetricKey> key1(
- base::SymmetricKey::GenerateRandomKey(base::SymmetricKey::AES, 256));
- ASSERT_TRUE(NULL != key1.get());
- std::string raw_key1;
- EXPECT_TRUE(key1->GetRawKey(&raw_key1));
-
- scoped_ptr<base::SymmetricKey> key2(
- base::SymmetricKey::Import(base::SymmetricKey::AES, raw_key1));
- ASSERT_TRUE(NULL != key2.get());
-
- std::string raw_key2;
- EXPECT_TRUE(key2->GetRawKey(&raw_key2));
-
- EXPECT_EQ(raw_key1, raw_key2);
-}
-
-TEST(SymmetricKeyTest, ImportDerivedKey) {
- scoped_ptr<base::SymmetricKey> key1(
- base::SymmetricKey::DeriveKeyFromPassword(base::SymmetricKey::HMAC_SHA1,
- "password", "somesalt", 1024,
- 160));
- ASSERT_TRUE(NULL != key1.get());
- std::string raw_key1;
- EXPECT_TRUE(key1->GetRawKey(&raw_key1));
-
- scoped_ptr<base::SymmetricKey> key2(
- base::SymmetricKey::Import(base::SymmetricKey::HMAC_SHA1, raw_key1));
- ASSERT_TRUE(NULL != key2.get());
-
- std::string raw_key2;
- EXPECT_TRUE(key2->GetRawKey(&raw_key2));
-
- EXPECT_EQ(raw_key1, raw_key2);
-}
-
-struct PBKDF2TestVector {
- base::SymmetricKey::Algorithm algorithm;
- const char* password;
- const char* salt;
- unsigned int rounds;
- unsigned int key_size_in_bits;
- const char* expected; // ASCII encoded hex bytes
-};
-
-class SymmetricKeyDeriveKeyFromPasswordTest
- : public testing::TestWithParam<PBKDF2TestVector> {
-};
-
-TEST_P(SymmetricKeyDeriveKeyFromPasswordTest, DeriveKeyFromPassword) {
- PBKDF2TestVector test_data(GetParam());
-#if defined(OS_MACOSX)
- // The OS X crypto libraries have minimum salt and iteration requirements
- // so some of the tests below will cause them to barf. Skip these.
- if (strlen(test_data.salt) < 8 || test_data.rounds < 1000) {
- VLOG(1) << "Skipped test vector for " << test_data.expected;
- return;
- }
-#endif // OS_MACOSX
-
- scoped_ptr<base::SymmetricKey> key(
- base::SymmetricKey::DeriveKeyFromPassword(
- test_data.algorithm,
- test_data.password, test_data.salt,
- test_data.rounds, test_data.key_size_in_bits));
- ASSERT_TRUE(NULL != key.get());
-
- std::string raw_key;
- key->GetRawKey(&raw_key);
- EXPECT_EQ(test_data.key_size_in_bits / 8, raw_key.size());
- EXPECT_EQ(test_data.expected,
- StringToLowerASCII(base::HexEncode(raw_key.data(),
- raw_key.size())));
-}
-
-static const PBKDF2TestVector kTestVectors[] = {
- // These tests come from
- // http://www.ietf.org/id/draft-josefsson-pbkdf2-test-vectors-00.txt
- {
- base::SymmetricKey::HMAC_SHA1,
- "password",
- "salt",
- 1,
- 160,
- "0c60c80f961f0e71f3a9b524af6012062fe037a6",
- },
- {
- base::SymmetricKey::HMAC_SHA1,
- "password",
- "salt",
- 2,
- 160,
- "ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957",
- },
- {
- base::SymmetricKey::HMAC_SHA1,
- "password",
- "salt",
- 4096,
- 160,
- "4b007901b765489abead49d926f721d065a429c1",
- },
- // This test takes over 30s to run on the trybots.
-#if 0
- {
- base::SymmetricKey::HMAC_SHA1,
- "password",
- "salt",
- 16777216,
- 160,
- "eefe3d61cd4da4e4e9945b3d6ba2158c2634e984",
- },
-#endif
-
- // These tests come from RFC 3962, via BSD source code at
- // http://www.openbsd.org/cgi-bin/cvsweb/src/sbin/bioctl/pbkdf2.c?rev=HEAD&content-type=text/plain
- {
- base::SymmetricKey::HMAC_SHA1,
- "password",
- "ATHENA.MIT.EDUraeburn",
- 1,
- 160,
- "cdedb5281bb2f801565a1122b25635150ad1f7a0",
- },
- {
- base::SymmetricKey::HMAC_SHA1,
- "password",
- "ATHENA.MIT.EDUraeburn",
- 2,
- 160,
- "01dbee7f4a9e243e988b62c73cda935da05378b9",
- },
- {
- base::SymmetricKey::HMAC_SHA1,
- "password",
- "ATHENA.MIT.EDUraeburn",
- 1200,
- 160,
- "5c08eb61fdf71e4e4ec3cf6ba1f5512ba7e52ddb",
- },
- {
- base::SymmetricKey::HMAC_SHA1,
- "password",
- "\0224VxxV4\022", /* 0x1234567878563412 */
- 5,
- 160,
- "d1daa78615f287e6a1c8b120d7062a493f98d203",
- },
- {
- base::SymmetricKey::HMAC_SHA1,
- "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
- "pass phrase equals block size",
- 1200,
- 160,
- "139c30c0966bc32ba55fdbf212530ac9c5ec59f1",
- },
- {
- base::SymmetricKey::HMAC_SHA1,
- "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
- "pass phrase exceeds block size",
- 1200,
- 160,
- "9ccad6d468770cd51b10e6a68721be611a8b4d28",
- },
- {
- base::SymmetricKey::HMAC_SHA1,
- "\360\235\204\236", /* g-clef (0xf09d849e) */
- "EXAMPLE.COMpianist",
- 50,
- 160,
- "6b9cf26d45455a43a5b8bb276a403b39e7fe37a0",
- },
-
- // Regression tests for AES keys, derived from the Linux NSS implementation.
- {
- base::SymmetricKey::AES,
- "A test password",
- "saltsalt",
- 1,
- 256,
- "44899a7777f0e6e8b752f875f02044b8ac593de146de896f2e8a816e315a36de",
- },
- {
- base::SymmetricKey::AES,
- "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
- "pass phrase exceeds block size",
- 20,
- 256,
- "e0739745dc28b8721ba402e05214d2ac1eab54cf72bee1fba388297a09eb493c",
- },
-};
-
-INSTANTIATE_TEST_CASE_P(, SymmetricKeyDeriveKeyFromPasswordTest,
- testing::ValuesIn(kTestVectors));
diff --git a/base/crypto/symmetric_key_win.cc b/base/crypto/symmetric_key_win.cc
deleted file mode 100644
index 87d715a..0000000
--- a/base/crypto/symmetric_key_win.cc
+++ /dev/null
@@ -1,536 +0,0 @@
-// 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.
-
-#include "base/crypto/symmetric_key.h"
-
-#include <winsock2.h> // For htonl.
-
-#include <vector>
-
-// TODO(wtc): replace scoped_array by std::vector.
-#include "base/scoped_ptr.h"
-
-namespace base {
-
-namespace {
-
-// The following is a non-public Microsoft header documented in MSDN under
-// CryptImportKey / CryptExportKey. Following the header is the byte array of
-// the actual plaintext key.
-struct PlaintextBlobHeader {
- BLOBHEADER hdr;
- DWORD cbKeySize;
-};
-
-// CryptoAPI makes use of three distinct ALG_IDs for AES, rather than just
-// CALG_AES (which exists, but depending on the functions you are calling, may
-// result in function failure, whereas the subtype would succeed).
-ALG_ID GetAESAlgIDForKeySize(size_t key_size_in_bits) {
- // Only AES-128/-192/-256 is supported in CryptoAPI.
- switch (key_size_in_bits) {
- case 128:
- return CALG_AES_128;
- case 192:
- return CALG_AES_192;
- case 256:
- return CALG_AES_256;
- default:
- NOTREACHED();
- return 0;
- }
-};
-
-// Imports a raw/plaintext key of |key_size| stored in |*key_data| into a new
-// key created for the specified |provider|. |alg| contains the algorithm of
-// the key being imported.
-// If |key_data| is intended to be used as an HMAC key, then |alg| should be
-// CALG_HMAC.
-// If successful, returns true and stores the imported key in |*key|.
-// TODO(wtc): use this function in hmac_win.cc.
-bool ImportRawKey(HCRYPTPROV provider,
- ALG_ID alg,
- const void* key_data, DWORD key_size,
- ScopedHCRYPTKEY* key) {
- DCHECK_GT(key_size, 0);
-
- DWORD actual_size = sizeof(PlaintextBlobHeader) + key_size;
- std::vector<BYTE> tmp_data(actual_size);
- BYTE* actual_key = &tmp_data[0];
- memcpy(actual_key + sizeof(PlaintextBlobHeader), key_data, key_size);
- PlaintextBlobHeader* key_header =
- reinterpret_cast<PlaintextBlobHeader*>(actual_key);
- memset(key_header, 0, sizeof(PlaintextBlobHeader));
-
- key_header->hdr.bType = PLAINTEXTKEYBLOB;
- key_header->hdr.bVersion = CUR_BLOB_VERSION;
- key_header->hdr.aiKeyAlg = alg;
-
- key_header->cbKeySize = key_size;
-
- HCRYPTKEY unsafe_key = NULL;
- DWORD flags = CRYPT_EXPORTABLE;
- if (alg == CALG_HMAC) {
- // Though it may appear odd that IPSEC and RC2 are being used, this is
- // done in accordance with Microsoft's FIPS 140-2 Security Policy for the
- // RSA Enhanced Provider, as the approved means of using arbitrary HMAC
- // key material.
- key_header->hdr.aiKeyAlg = CALG_RC2;
- flags |= CRYPT_IPSEC_HMAC_KEY;
- }
-
- BOOL ok =
- CryptImportKey(provider, actual_key, actual_size, 0, flags, &unsafe_key);
-
- // Clean up the temporary copy of key, regardless of whether it was imported
- // sucessfully or not.
- SecureZeroMemory(actual_key, actual_size);
-
- if (!ok)
- return false;
-
- key->reset(unsafe_key);
- return true;
-}
-
-// Attempts to generate a random AES key of |key_size_in_bits|. Returns true
-// if generation is successful, storing the generated key in |*key| and the
-// key provider (CSP) in |*provider|.
-bool GenerateAESKey(size_t key_size_in_bits,
- ScopedHCRYPTPROV* provider,
- ScopedHCRYPTKEY* key) {
- DCHECK(provider);
- DCHECK(key);
-
- ALG_ID alg = GetAESAlgIDForKeySize(key_size_in_bits);
- if (alg == 0)
- return false;
-
- ScopedHCRYPTPROV safe_provider;
- // Note: The only time NULL is safe to be passed as pszContainer is when
- // dwFlags contains CRYPT_VERIFYCONTEXT, as all keys generated and/or used
- // will be treated as ephemeral keys and not persisted.
- BOOL ok = CryptAcquireContext(safe_provider.receive(), NULL, NULL,
- PROV_RSA_AES, CRYPT_VERIFYCONTEXT);
- if (!ok)
- return false;
-
- ScopedHCRYPTKEY safe_key;
- // In the FIPS 140-2 Security Policy for CAPI on XP/Vista+, Microsoft notes
- // that CryptGenKey makes use of the same functionality exposed via
- // CryptGenRandom. The reason this is being used, as opposed to
- // CryptGenRandom and CryptImportKey is for compliance with the security
- // policy
- ok = CryptGenKey(safe_provider.get(), alg, CRYPT_EXPORTABLE,
- safe_key.receive());
- if (!ok)
- return false;
-
- key->swap(safe_key);
- provider->swap(safe_provider);
-
- return true;
-}
-
-// Returns true if the HMAC key size meets the requirement of FIPS 198
-// Section 3. |alg| is the hash function used in the HMAC.
-bool CheckHMACKeySize(size_t key_size_in_bits, ALG_ID alg) {
- DWORD hash_size = 0;
- switch (alg) {
- case CALG_SHA1:
- hash_size = 20;
- break;
- case CALG_SHA_256:
- hash_size = 32;
- break;
- case CALG_SHA_384:
- hash_size = 48;
- break;
- case CALG_SHA_512:
- hash_size = 64;
- break;
- }
- if (hash_size == 0)
- return false;
-
- // An HMAC key must be >= L/2, where L is the output size of the hash
- // function being used.
- return (key_size_in_bits >= (hash_size / 2 * 8) &&
- (key_size_in_bits % 8) == 0);
-}
-
-// Attempts to generate a random, |key_size_in_bits|-long HMAC key, for use
-// with the hash function |alg|.
-// |key_size_in_bits| must be >= 1/2 the hash size of |alg| for security.
-// Returns true if generation is successful, storing the generated key in
-// |*key| and the key provider (CSP) in |*provider|.
-bool GenerateHMACKey(size_t key_size_in_bits,
- ALG_ID alg,
- ScopedHCRYPTPROV* provider,
- ScopedHCRYPTKEY* key,
- scoped_array<BYTE>* raw_key) {
- DCHECK(provider);
- DCHECK(key);
- DCHECK(raw_key);
-
- if (!CheckHMACKeySize(key_size_in_bits, alg))
- return false;
-
- ScopedHCRYPTPROV safe_provider;
- // See comment in GenerateAESKey as to why NULL is acceptable for the
- // container name.
- BOOL ok = CryptAcquireContext(safe_provider.receive(), NULL, NULL,
- PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
- if (!ok)
- return false;
-
- DWORD key_size_in_bytes = key_size_in_bits / 8;
- scoped_array<BYTE> random(new BYTE[key_size_in_bytes]);
- ok = CryptGenRandom(safe_provider, key_size_in_bytes, random.get());
- if (!ok)
- return false;
-
- ScopedHCRYPTKEY safe_key;
- bool rv = ImportRawKey(safe_provider, CALG_HMAC, random.get(),
- key_size_in_bytes, &safe_key);
- if (rv) {
- key->swap(safe_key);
- provider->swap(safe_provider);
- raw_key->swap(random);
- }
-
- SecureZeroMemory(random.get(), key_size_in_bytes);
- return rv;
-}
-
-// Attempts to create an HMAC hash instance using the specified |provider|
-// and |key|. The inner hash function will be |hash_alg|. If successful,
-// returns true and stores the hash in |*hash|.
-// TODO(wtc): use this function in hmac_win.cc.
-bool CreateHMACHash(HCRYPTPROV provider,
- HCRYPTKEY key,
- ALG_ID hash_alg,
- ScopedHCRYPTHASH* hash) {
- ScopedHCRYPTHASH safe_hash;
- BOOL ok = CryptCreateHash(provider, CALG_HMAC, key, 0, safe_hash.receive());
- if (!ok)
- return false;
-
- HMAC_INFO hmac_info;
- memset(&hmac_info, 0, sizeof(hmac_info));
- hmac_info.HashAlgid = hash_alg;
-
- ok = CryptSetHashParam(safe_hash, HP_HMAC_INFO,
- reinterpret_cast<const BYTE*>(&hmac_info), 0);
- if (!ok)
- return false;
-
- hash->swap(safe_hash);
- return true;
-}
-
-// Computes a block of the derived key using the PBKDF2 function F for the
-// specified |block_index| using the PRF |hash|, writing the output to
-// |output_buf|.
-// |output_buf| must have enough space to accomodate the output of the PRF
-// specified by |hash|.
-// Returns true if the block was successfully computed.
-bool ComputePBKDF2Block(HCRYPTHASH hash,
- DWORD hash_size,
- const std::string& salt,
- size_t iterations,
- uint32 block_index,
- BYTE* output_buf) {
- // From RFC 2898:
- // 3. <snip> The function F is defined as the exclusive-or sum of the first
- // c iterates of the underlying pseudorandom function PRF applied to the
- // password P and the concatenation of the salt S and the block index i:
- // F (P, S, c, i) = U_1 \xor U_2 \xor ... \xor U_c
- // where
- // U_1 = PRF(P, S || INT (i))
- // U_2 = PRF(P, U_1)
- // ...
- // U_c = PRF(P, U_{c-1})
- ScopedHCRYPTHASH safe_hash;
- BOOL ok = CryptDuplicateHash(hash, NULL, 0, safe_hash.receive());
- if (!ok)
- return false;
-
- // Iteration U_1: Compute PRF for S.
- ok = CryptHashData(safe_hash, reinterpret_cast<const BYTE*>(salt.data()),
- salt.size(), 0);
- if (!ok)
- return false;
-
- // Iteration U_1: and append (big-endian) INT (i).
- uint32 big_endian_block_index = htonl(block_index);
- ok = CryptHashData(safe_hash,
- reinterpret_cast<BYTE*>(&big_endian_block_index),
- sizeof(big_endian_block_index), 0);
-
- std::vector<BYTE> hash_value(hash_size);
-
- DWORD size = hash_size;
- ok = CryptGetHashParam(safe_hash, HP_HASHVAL, &hash_value[0], &size, 0);
- if (!ok || size != hash_size)
- return false;
-
- memcpy(output_buf, &hash_value[0], hash_size);
-
- // Iteration 2 - c: Compute U_{iteration} by applying the PRF to
- // U_{iteration - 1}, then xor the resultant hash with |output|, which
- // contains U_1 ^ U_2 ^ ... ^ U_{iteration - 1}.
- for (size_t iteration = 2; iteration <= iterations; ++iteration) {
- safe_hash.reset();
- ok = CryptDuplicateHash(hash, NULL, 0, safe_hash.receive());
- if (!ok)
- return false;
-
- ok = CryptHashData(safe_hash, &hash_value[0], hash_size, 0);
- if (!ok)
- return false;
-
- size = hash_size;
- ok = CryptGetHashParam(safe_hash, HP_HASHVAL, &hash_value[0], &size, 0);
- if (!ok || size != hash_size)
- return false;
-
- for (int i = 0; i < hash_size; ++i)
- output_buf[i] ^= hash_value[i];
- }
-
- return true;
-}
-
-} // namespace
-
-SymmetricKey::~SymmetricKey() {
- // TODO(wtc): create a "secure" string type that zeroes itself in the
- // destructor.
- if (!raw_key_.empty())
- SecureZeroMemory(const_cast<char *>(raw_key_.data()), raw_key_.size());
-}
-
-// static
-SymmetricKey* SymmetricKey::GenerateRandomKey(Algorithm algorithm,
- size_t key_size_in_bits) {
- DCHECK_GE(key_size_in_bits, 8);
-
- ScopedHCRYPTPROV provider;
- ScopedHCRYPTKEY key;
-
- bool ok = false;
- scoped_array<BYTE> raw_key;
-
- switch (algorithm) {
- case AES:
- ok = GenerateAESKey(key_size_in_bits, &provider, &key);
- break;
- case HMAC_SHA1:
- ok = GenerateHMACKey(key_size_in_bits, CALG_SHA1, &provider,
- &key, &raw_key);
- break;
- }
-
- if (!ok) {
- NOTREACHED();
- return NULL;
- }
-
- size_t key_size_in_bytes = key_size_in_bits / 8;
- if (raw_key == NULL)
- key_size_in_bytes = 0;
-
- SymmetricKey* result = new SymmetricKey(provider.release(),
- key.release(),
- raw_key.get(),
- key_size_in_bytes);
- if (raw_key != NULL)
- SecureZeroMemory(raw_key.get(), key_size_in_bytes);
-
- return result;
-}
-
-// static
-SymmetricKey* SymmetricKey::DeriveKeyFromPassword(Algorithm algorithm,
- const std::string& password,
- const std::string& salt,
- size_t iterations,
- size_t key_size_in_bits) {
- // CryptoAPI lacks routines to perform PBKDF2 derivation as specified
- // in RFC 2898, so it must be manually implemented. Only HMAC-SHA1 is
- // supported as the PRF.
-
- // While not used until the end, sanity-check the input before proceeding
- // with the expensive computation.
- DWORD provider_type = 0;
- ALG_ID alg = 0;
- switch (algorithm) {
- case AES:
- provider_type = PROV_RSA_AES;
- alg = GetAESAlgIDForKeySize(key_size_in_bits);
- break;
- case HMAC_SHA1:
- provider_type = PROV_RSA_FULL;
- alg = CALG_HMAC;
- break;
- default:
- NOTREACHED();
- break;
- }
- if (provider_type == 0 || alg == 0)
- return NULL;
-
- ScopedHCRYPTPROV provider;
- BOOL ok = CryptAcquireContext(provider.receive(), NULL, NULL, provider_type,
- CRYPT_VERIFYCONTEXT);
- if (!ok)
- return NULL;
-
- // Convert the user password into a key suitable to be fed into the PRF
- // function.
- ScopedHCRYPTKEY password_as_key;
- BYTE* password_as_bytes =
- const_cast<BYTE*>(reinterpret_cast<const BYTE*>(password.data()));
- if (!ImportRawKey(provider, CALG_HMAC, password_as_bytes,
- password.size(), &password_as_key))
- return NULL;
-
- // Configure the PRF function. Only HMAC variants are supported, with the
- // only hash function supported being SHA1.
- // TODO(rsleevi): Support SHA-256 on XP SP3+.
- ScopedHCRYPTHASH prf;
- if (!CreateHMACHash(provider, password_as_key, CALG_SHA1, &prf))
- return NULL;
-
- DWORD hLen = 0;
- DWORD param_size = sizeof(hLen);
- ok = CryptGetHashParam(prf, HP_HASHSIZE,
- reinterpret_cast<BYTE*>(&hLen), &param_size, 0);
- if (!ok || hLen == 0)
- return NULL;
-
- // 1. If dkLen > (2^32 - 1) * hLen, output "derived key too long" and stop.
- size_t dkLen = key_size_in_bits / 8;
- DCHECK_GT(dkLen, 0);
-
- if ((dkLen / hLen) > 0xFFFFFFFF) {
- DLOG(ERROR) << "Derived key too long.";
- return NULL;
- }
-
- // 2. Let l be the number of hLen-octet blocks in the derived key,
- // rounding up, and let r be the number of octets in the last
- // block:
- size_t L = (dkLen + hLen - 1) / hLen;
- DCHECK_GT(L, 0);
-
- size_t total_generated_size = L * hLen;
- std::vector<BYTE> generated_key(total_generated_size);
- BYTE* block_offset = &generated_key[0];
-
- // 3. For each block of the derived key apply the function F defined below
- // to the password P, the salt S, the iteration count c, and the block
- // index to compute the block:
- // T_1 = F (P, S, c, 1)
- // T_2 = F (P, S, c, 2)
- // ...
- // T_l = F (P, S, c, l)
- // <snip>
- // 4. Concatenate the blocks and extract the first dkLen octets to produce
- // a derived key DK:
- // DK = T_1 || T_2 || ... || T_l<0..r-1>
- for (uint32 block_index = 1; block_index <= L; ++block_index) {
- if (!ComputePBKDF2Block(prf, hLen, salt, iterations, block_index,
- block_offset))
- return NULL;
- block_offset += hLen;
- }
-
- // Convert the derived key bytes into a key handle for the desired algorithm.
- ScopedHCRYPTKEY key;
- if (!ImportRawKey(provider, alg, &generated_key[0], dkLen, &key))
- return NULL;
-
- SymmetricKey* result = new SymmetricKey(provider.release(), key.release(),
- &generated_key[0], dkLen);
-
- SecureZeroMemory(&generated_key[0], total_generated_size);
-
- return result;
-}
-
-// static
-SymmetricKey* SymmetricKey::Import(Algorithm algorithm,
- const std::string& raw_key) {
- DWORD provider_type = 0;
- ALG_ID alg = 0;
- switch (algorithm) {
- case AES:
- provider_type = PROV_RSA_AES;
- alg = GetAESAlgIDForKeySize(raw_key.size() * 8);
- break;
- case HMAC_SHA1:
- provider_type = PROV_RSA_FULL;
- alg = CALG_HMAC;
- break;
- default:
- NOTREACHED();
- break;
- }
- if (provider_type == 0 || alg == 0)
- return NULL;
-
- ScopedHCRYPTPROV provider;
- BOOL ok = CryptAcquireContext(provider.receive(), NULL, NULL, provider_type,
- CRYPT_VERIFYCONTEXT);
- if (!ok)
- return NULL;
-
- ScopedHCRYPTKEY key;
- if (!ImportRawKey(provider, alg, raw_key.data(), raw_key.size(), &key))
- return NULL;
-
- return new SymmetricKey(provider.release(), key.release(),
- raw_key.data(), raw_key.size());
-}
-
-bool SymmetricKey::GetRawKey(std::string* raw_key) {
- // Short circuit for when the key was supplied to the constructor.
- if (!raw_key_.empty()) {
- *raw_key = raw_key_;
- return true;
- }
-
- DWORD size = 0;
- BOOL ok = CryptExportKey(key_, 0, PLAINTEXTKEYBLOB, 0, NULL, &size);
- if (!ok)
- return false;
-
- std::vector<BYTE> result(size);
-
- ok = CryptExportKey(key_, 0, PLAINTEXTKEYBLOB, 0, &result[0], &size);
- if (!ok)
- return false;
-
- PlaintextBlobHeader* header =
- reinterpret_cast<PlaintextBlobHeader*>(&result[0]);
- raw_key->assign(reinterpret_cast<char*>(&result[sizeof(*header)]),
- header->cbKeySize);
-
- SecureZeroMemory(&result[0], size);
-
- return true;
-}
-
-SymmetricKey::SymmetricKey(HCRYPTPROV provider,
- HCRYPTKEY key,
- const void* key_data, size_t key_size_in_bytes)
- : provider_(provider), key_(key) {
- if (key_data) {
- raw_key_.assign(reinterpret_cast<const char*>(key_data),
- key_size_in_bytes);
- }
-}
-
-} // namespace base
diff --git a/base/debug/debug_on_start_win.h b/base/debug/debug_on_start_win.h
index 5a1081d..4a5c120 100644
--- a/base/debug/debug_on_start_win.h
+++ b/base/debug/debug_on_start_win.h
@@ -24,6 +24,11 @@
namespace base {
namespace debug {
+// There is no way for this code, as currently implemented, to work across DLLs.
+// TODO(rvargas): It looks like we really don't use this code, at least not for
+// Chrome. Figure out if it's really worth implementing something simpler.
+#if !defined(BASE_DLL)
+
// Debug on start functions and data.
class DebugOnStart {
public:
@@ -69,6 +74,8 @@ DECLSPEC_SELECTANY DebugOnStart::PIFV debug_on_start = &DebugOnStart::Init;
#endif // _WIN64
+#endif // defined(BASE_DLL)
+
} // namespace debug
} // namespace base
diff --git a/base/debug/debugger.h b/base/debug/debugger.h
index 77bde0d..bb937a0 100644
--- a/base/debug/debugger.h
+++ b/base/debug/debugger.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -10,16 +10,18 @@
#define BASE_DEBUG_DEBUGGER_H
#pragma once
+#include "base/base_api.h"
+
namespace base {
namespace debug {
// Starts the registered system-wide JIT debugger to attach it to specified
// process.
-bool SpawnDebuggerOnProcess(unsigned process_id);
+BASE_API bool SpawnDebuggerOnProcess(unsigned process_id);
// Waits wait_seconds seconds for a debugger to attach to the current process.
// When silent is false, an exception is thrown when a debugger is detected.
-bool WaitForDebugger(int wait_seconds, bool silent);
+BASE_API bool WaitForDebugger(int wait_seconds, bool silent);
// Returns true if the given process is being run under a debugger.
//
@@ -28,18 +30,18 @@ bool WaitForDebugger(int wait_seconds, bool silent);
//
// WARNING: Because of this, on OS X, a call MUST be made to this function
// BEFORE the sandbox is enabled.
-bool BeingDebugged();
+BASE_API bool BeingDebugged();
// Break into the debugger, assumes a debugger is present.
-void BreakDebugger();
+BASE_API void BreakDebugger();
// Used in test code, this controls whether showing dialogs and breaking into
// the debugger is suppressed for debug errors, even in debug mode (normally
// release mode doesn't do this stuff -- this is controlled separately).
// Normally UI is not suppressed. This is normally used when running automated
// tests where we want a crash rather than a dialog or a debugger.
-void SetSuppressDebugUI(bool suppress);
-bool IsDebugUISuppressed();
+BASE_API void SetSuppressDebugUI(bool suppress);
+BASE_API bool IsDebugUISuppressed();
} // namespace debug
} // namespace base
diff --git a/base/debug/debugger_posix.cc b/base/debug/debugger_posix.cc
index 2eacaf9..bf90a0f 100644
--- a/base/debug/debugger_posix.cc
+++ b/base/debug/debugger_posix.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -10,6 +10,7 @@
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
+#include <sys/param.h>
#include <sys/stat.h>
#if !defined(OS_NACL)
#include <sys/sysctl.h>
@@ -33,8 +34,8 @@
#include "base/basictypes.h"
#include "base/eintr_wrapper.h"
#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
#include "base/safe_strerror_posix.h"
-#include "base/scoped_ptr.h"
#include "base/string_piece.h"
#include "base/stringprintf.h"
diff --git a/base/debug/leak_tracker_unittest.cc b/base/debug/leak_tracker_unittest.cc
index 2e6a9a5..99df4c1 100644
--- a/base/debug/leak_tracker_unittest.cc
+++ b/base/debug/leak_tracker_unittest.cc
@@ -1,9 +1,9 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
#include "base/debug/leak_tracker.h"
-#include "base/scoped_ptr.h"
+#include "base/memory/scoped_ptr.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace base {
diff --git a/base/debug/stack_trace.cc b/base/debug/stack_trace.cc
index 5be4c5c..7c44f7a 100644
--- a/base/debug/stack_trace.cc
+++ b/base/debug/stack_trace.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -10,7 +10,7 @@ namespace debug {
StackTrace::~StackTrace() {
}
-const void *const *StackTrace::Addresses(size_t* count) {
+const void *const *StackTrace::Addresses(size_t* count) const {
*count = count_;
if (count_)
return trace_;
diff --git a/base/debug/stack_trace.h b/base/debug/stack_trace.h
index 8afc32c..acc7223 100644
--- a/base/debug/stack_trace.h
+++ b/base/debug/stack_trace.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -8,6 +8,7 @@
#include <iosfwd>
+#include "base/base_api.h"
#include "build/build_config.h"
#if defined(OS_WIN)
@@ -20,7 +21,7 @@ namespace debug {
// A stacktrace can be helpful in debugging. For example, you can include a
// stacktrace member in a object (probably around #ifndef NDEBUG) so that you
// can later see where the given object was created from.
-class StackTrace {
+class BASE_API StackTrace {
public:
// Creates a stacktrace from the current location.
StackTrace();
@@ -38,13 +39,13 @@ class StackTrace {
// Gets an array of instruction pointer values. |*count| will be set to the
// number of elements in the returned array.
- const void* const* Addresses(size_t* count);
+ const void* const* Addresses(size_t* count) const;
// Prints a backtrace to stderr
- void PrintBacktrace();
+ void PrintBacktrace() const;
// Resolves backtrace to symbols and write to stream.
- void OutputToStream(std::ostream* os);
+ void OutputToStream(std::ostream* os) const;
private:
// From http://msdn.microsoft.com/en-us/library/bb204633.aspx,
diff --git a/base/debug/stack_trace_posix.cc b/base/debug/stack_trace_posix.cc
index 879110d..958cfdf 100644
--- a/base/debug/stack_trace_posix.cc
+++ b/base/debug/stack_trace_posix.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -9,6 +9,7 @@
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
+#include <sys/param.h>
#include <sys/stat.h>
#include <sys/sysctl.h>
#include <sys/types.h>
@@ -30,8 +31,8 @@
#include "base/basictypes.h"
#include "base/eintr_wrapper.h"
#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
#include "base/safe_strerror_posix.h"
-#include "base/scoped_ptr.h"
#include "base/string_piece.h"
#include "base/stringprintf.h"
@@ -105,7 +106,7 @@ void DemangleSymbols(std::string* text) {
// names and attach these. Otherwise just use raw addresses. Returns true
// if any symbol name is resolved. Returns false on error and *may* fill
// in |error_message| if an error message is available.
-bool GetBacktraceStrings(void **trace, int size,
+bool GetBacktraceStrings(void *const *trace, int size,
std::vector<std::string>* trace_strings,
std::string* error_message) {
#ifdef ANDROID
@@ -168,11 +169,16 @@ StackTrace::StackTrace() {
count_ = std::max(backtrace(trace_, arraysize(trace_)), 0);
}
+<<<<<<< HEAD
void StackTrace::PrintBacktrace() {
#if (defined(OS_MACOSX) && MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5) || defined(ANDROID)
#if defined(ANDROID)
return;
#else
+=======
+void StackTrace::PrintBacktrace() const {
+#if defined(OS_MACOSX) && MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
+>>>>>>> chromium.org at r12.0.742.93
if (backtrace_symbols_fd == NULL)
return;
#endif // ANDROID
@@ -185,11 +191,16 @@ void StackTrace::PrintBacktrace() {
}
}
+<<<<<<< HEAD
void StackTrace::OutputToStream(std::ostream* os) {
#if (defined(OS_MACOSX) && MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5) || defined(ANDROID)
#if defined(ANDROID)
return;
#else
+=======
+void StackTrace::OutputToStream(std::ostream* os) const {
+#if defined(OS_MACOSX) && MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
+>>>>>>> chromium.org at r12.0.742.93
if (backtrace_symbols == NULL)
return;
#endif // ANDROID
diff --git a/base/debug/stack_trace_win.cc b/base/debug/stack_trace_win.cc
index 510d35b..97376a2 100644
--- a/base/debug/stack_trace_win.cc
+++ b/base/debug/stack_trace_win.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -11,7 +11,7 @@
#include "base/basictypes.h"
#include "base/logging.h"
-#include "base/singleton.h"
+#include "base/memory/singleton.h"
#include "base/synchronization/lock.h"
namespace base {
@@ -174,11 +174,11 @@ StackTrace::StackTrace(EXCEPTION_POINTERS* exception_pointers) {
}
}
-void StackTrace::PrintBacktrace() {
+void StackTrace::PrintBacktrace() const {
OutputToStream(&std::cerr);
}
-void StackTrace::OutputToStream(std::ostream* os) {
+void StackTrace::OutputToStream(std::ostream* os) const {
SymbolContext* context = SymbolContext::GetInstance();
DWORD error = context->init_error();
if (error != ERROR_SUCCESS) {
diff --git a/base/debug/trace_event.h b/base/debug/trace_event.h
index e5c2cbd..6e818e1 100644
--- a/base/debug/trace_event.h
+++ b/base/debug/trace_event.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -31,8 +31,8 @@
#include <string>
-#include "base/scoped_ptr.h"
-#include "base/singleton.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/singleton.h"
#include "base/synchronization/lock.h"
#include "base/time.h"
#include "base/timer.h"
diff --git a/base/debug/trace_event_win.cc b/base/debug/trace_event_win.cc
index 005ff62..4929944 100644
--- a/base/debug/trace_event_win.cc
+++ b/base/debug/trace_event_win.cc
@@ -1,11 +1,11 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
#include "base/debug/trace_event_win.h"
#include "base/logging.h"
-#include "base/singleton.h"
+#include "base/memory/singleton.h"
#include <initguid.h> // NOLINT
namespace base {
diff --git a/base/debug/trace_event_win.h b/base/debug/trace_event_win.h
index a1c79ba..9049bdb 100644
--- a/base/debug/trace_event_win.h
+++ b/base/debug/trace_event_win.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -8,6 +8,8 @@
#pragma once
#include <string>
+
+#include "base/base_api.h"
#include "base/win/event_trace_provider.h"
#define TRACE_EVENT_BEGIN(name, id, extra) \
@@ -40,7 +42,7 @@ namespace debug {
// This EtwTraceProvider subclass implements ETW logging
// for the macros above on Windows.
-class TraceLog : public base::win::EtwTraceProvider {
+class BASE_API TraceLog : public base::win::EtwTraceProvider {
public:
enum EventType {
EVENT_BEGIN,
@@ -117,13 +119,13 @@ class TraceLog : public base::win::EtwTraceProvider {
};
// The ETW trace provider GUID.
-extern const GUID kChromeTraceProviderName;
+BASE_API extern const GUID kChromeTraceProviderName;
// The ETW event class GUID for 32 bit events.
-extern const GUID kTraceEventClass32;
+BASE_API extern const GUID kTraceEventClass32;
// The ETW event class GUID for 64 bit events.
-extern const GUID kTraceEventClass64;
+BASE_API extern const GUID kTraceEventClass64;
// The ETW event types, IDs 0x00-0x09 are reserved, so start at 0x10.
const base::win::EtwEventType kTraceEventTypeBegin = 0x10;
diff --git a/base/environment.cc b/base/environment.cc
index 9ccc078..0bfc68e 100644
--- a/base/environment.cc
+++ b/base/environment.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -13,7 +13,7 @@
#include "base/string_util.h"
#if defined(OS_WIN)
-#include "base/scoped_ptr.h"
+#include "base/memory/scoped_ptr.h"
#include "base/utf_string_conversions.h"
#endif
diff --git a/base/environment.h b/base/environment.h
index 4c0691b..cf71724 100644
--- a/base/environment.h
+++ b/base/environment.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -8,7 +8,8 @@
#include <string>
-#include "base/basictypes.h"
+#include "base/base_api.h"
+#include "build/build_config.h"
namespace base {
@@ -20,7 +21,7 @@ extern const char kHome[];
} // namespace env_vars
-class Environment {
+class BASE_API Environment {
public:
virtual ~Environment();
diff --git a/base/environment_unittest.cc b/base/environment_unittest.cc
index d1ce503..b6654c9 100644
--- a/base/environment_unittest.cc
+++ b/base/environment_unittest.cc
@@ -1,9 +1,9 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
#include "base/environment.h"
-#include "base/scoped_ptr.h"
+#include "base/memory/scoped_ptr.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/platform_test.h"
diff --git a/base/event_recorder.cc b/base/event_recorder.cc
index 1119b4f..b247380 100644
--- a/base/event_recorder.cc
+++ b/base/event_recorder.cc
@@ -1,9 +1,8 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
-#include "build/build_config.h"
-
+#include <stddef.h>
#include <windows.h>
#include <mmsystem.h>
diff --git a/base/event_recorder.h b/base/event_recorder.h
index e4d8907..1f7aa61 100644
--- a/base/event_recorder.h
+++ b/base/event_recorder.h
@@ -6,11 +6,15 @@
#define BASE_EVENT_RECORDER_H_
#pragma once
+#include "base/base_api.h"
+#include "base/basictypes.h"
+#include "build/build_config.h"
+
#if defined(OS_WIN)
-#include <windows.h>
#include <stdio.h>
+#include <string.h>
+#include <windows.h>
#endif
-#include "base/basictypes.h"
class FilePath;
@@ -29,7 +33,7 @@ namespace base {
// Why? Imagine if the product had a "record a macro" feature.
// You might be recording globally, while recording or playing back
// a macro. I don't think two playbacks make sense.
-class EventRecorder {
+class BASE_API EventRecorder {
public:
// Get the singleton EventRecorder.
// We can only handle one recorder/player at a time.
diff --git a/base/file_descriptor_shuffle.cc b/base/file_descriptor_shuffle.cc
index 2bb156b..7ad9787 100644
--- a/base/file_descriptor_shuffle.cc
+++ b/base/file_descriptor_shuffle.cc
@@ -1,11 +1,12 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
#include "base/file_descriptor_shuffle.h"
-#include <errno.h>
#include <unistd.h>
+#include <stddef.h>
+#include <ostream>
#include "base/eintr_wrapper.h"
#include "base/logging.h"
diff --git a/base/file_path.cc b/base/file_path.cc
index 29ec7a8..0d0b40b 100644
--- a/base/file_path.cc
+++ b/base/file_path.cc
@@ -1,17 +1,13 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
-#include <algorithm>
-
#include "base/file_path.h"
-#if defined(OS_WIN)
-#include <windows.h>
-#elif defined(OS_MACOSX)
-#include <CoreFoundation/CoreFoundation.h>
-#endif
+#include <string.h>
+#include <algorithm>
+#include "base/basictypes.h"
#include "base/logging.h"
#include "base/pickle.h"
@@ -27,6 +23,12 @@
#include "base/third_party/icu/icu_utf.h"
#endif
+#if defined(OS_WIN)
+#include <windows.h>
+#elif defined(OS_MACOSX)
+#include <CoreFoundation/CoreFoundation.h>
+#endif
+
#if defined(FILE_PATH_USES_WIN_SEPARATORS)
const FilePath::CharType FilePath::kSeparators[] = FILE_PATH_LITERAL("\\/");
#else // FILE_PATH_USES_WIN_SEPARATORS
@@ -63,8 +65,8 @@ StringType::size_type FindDriveLetter(const StringType& path) {
}
#if defined(FILE_PATH_USES_DRIVE_LETTERS)
-bool EqualDriveLetterCaseInsensitive(const StringType a,
- const StringType b) {
+bool EqualDriveLetterCaseInsensitive(const StringType& a,
+ const StringType& b) {
size_t a_letter_pos = FindDriveLetter(a);
size_t b_letter_pos = FindDriveLetter(b);
@@ -532,9 +534,6 @@ std::string FilePath::MaybeAsASCII() const {
FilePath FilePath::FromWStringHack(const std::wstring& wstring) {
return FilePath(base::SysWideToNativeMB(wstring));
}
-std::wstring FilePath::ToWStringHack() const {
- return base::SysNativeMBToWide(path_);
-}
#elif defined(OS_WIN)
string16 FilePath::LossyDisplayName() const {
return path_;
@@ -550,9 +549,6 @@ std::string FilePath::MaybeAsASCII() const {
FilePath FilePath::FromWStringHack(const std::wstring& wstring) {
return FilePath(wstring);
}
-std::wstring FilePath::ToWStringHack() const {
- return path_;
-}
#endif
// static.
diff --git a/base/file_path.h b/base/file_path.h
index 1afa7a6..fd9260c 100644
--- a/base/file_path.h
+++ b/base/file_path.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -100,13 +100,16 @@
#define BASE_FILE_PATH_H_
#pragma once
+#include <stddef.h>
#include <string>
#include <vector>
-#include "base/basictypes.h"
+#include "base/base_api.h"
#include "base/compiler_specific.h"
#include "base/hash_tables.h"
+#include "base/string16.h"
#include "base/string_piece.h" // For implicit conversions.
+#include "build/build_config.h"
// Windows-style drive letter support and pathname separator characters can be
// enabled and disabled independently, to aid testing. These #defines are
@@ -121,7 +124,7 @@ class Pickle;
// An abstraction to isolate users from the differences between native
// pathnames on different platforms.
-class FilePath {
+class BASE_API FilePath {
public:
#if defined(OS_POSIX)
// On most platforms, native pathnames are char arrays, and the encoding
@@ -289,9 +292,9 @@ class FilePath {
std::string MaybeAsASCII() const;
// Older Chromium code assumes that paths are always wstrings.
- // These functions convert wstrings to/from FilePaths, and are
+ // This function converts wstrings to FilePaths, and is
// useful to smooth porting that old code to the FilePath API.
- // They have "Hack" in their names so people feel bad about using them.
+ // It has "Hack" its name so people feel bad about using it.
// http://code.google.com/p/chromium/issues/detail?id=24672
//
// If you are trying to be a good citizen and remove these, ask yourself:
@@ -305,7 +308,6 @@ class FilePath {
// LossyDisplayName() function, but keep in mind that you can't
// ever use the result of that again as a path.
static FilePath FromWStringHack(const std::wstring& wstring);
- std::wstring ToWStringHack() const;
// Static helper method to write a StringType to a pickle.
static void WriteStringTypeToPickle(Pickle* pickle,
@@ -386,7 +388,7 @@ namespace __gnu_cxx {
template<>
struct hash<FilePath> {
- std::size_t operator()(const FilePath& f) const {
+ size_t operator()(const FilePath& f) const {
return hash<FilePath::StringType>()(f.value());
}
};
diff --git a/base/file_util.h b/base/file_util.h
index 108c998..6fe9a3d 100644
--- a/base/file_util.h
+++ b/base/file_util.h
@@ -26,10 +26,11 @@
#include <string>
#include <vector>
+#include "base/base_api.h"
#include "base/basictypes.h"
#include "base/file_path.h"
+#include "base/memory/scoped_ptr.h"
#include "base/platform_file.h"
-#include "base/scoped_ptr.h"
#include "base/string16.h"
#if defined(OS_POSIX)
@@ -48,19 +49,19 @@ namespace file_util {
// Functions that operate purely on a path string w/o touching the filesystem:
// Returns true if the given path ends with a path separator character.
-bool EndsWithSeparator(const FilePath& path);
+BASE_API bool EndsWithSeparator(const FilePath& path);
// Makes sure that |path| ends with a separator IFF path is a directory that
// exists. Returns true if |path| is an existing directory, false otherwise.
-bool EnsureEndsWithSeparator(FilePath* path);
+BASE_API bool EnsureEndsWithSeparator(FilePath* path);
// Convert provided relative path into an absolute path. Returns false on
// error. On POSIX, this function fails if the path does not exist.
-bool AbsolutePath(FilePath* path);
+BASE_API bool AbsolutePath(FilePath* path);
// Returns true if |parent| contains |child|. Both paths are converted to
// absolute paths before doing the comparison.
-bool ContainsPath(const FilePath& parent, const FilePath& child);
+BASE_API bool ContainsPath(const FilePath& parent, const FilePath& child);
//-----------------------------------------------------------------------------
// Functions that involve filesystem access or modification:
@@ -73,15 +74,15 @@ bool ContainsPath(const FilePath& parent, const FilePath& child);
// timestmap of file creation time. If you need to avoid such
// mis-detection perfectly, you should wait one second before
// obtaining |file_time|.
-int CountFilesCreatedAfter(const FilePath& path,
- const base::Time& file_time);
+BASE_API int CountFilesCreatedAfter(const FilePath& path,
+ const base::Time& file_time);
// Returns the total number of bytes used by all the files under |root_path|.
// If the path does not exist the function returns 0.
//
// This function is implemented using the FileEnumerator class so it is not
// particularly speedy in any platform.
-int64 ComputeDirectorySize(const FilePath& root_path);
+BASE_API int64 ComputeDirectorySize(const FilePath& root_path);
// Returns the total number of bytes used by all files matching the provided
// |pattern|, on this |directory| (without recursion). If the path does not
@@ -89,8 +90,8 @@ int64 ComputeDirectorySize(const FilePath& root_path);
//
// This function is implemented using the FileEnumerator class so it is not
// particularly speedy in any platform.
-int64 ComputeFilesSize(const FilePath& directory,
- const FilePath::StringType& pattern);
+BASE_API int64 ComputeFilesSize(const FilePath& directory,
+ const FilePath::StringType& pattern);
// Deletes the given path, whether it's a file or a directory.
// If it's a directory, it's perfectly happy to delete all of the
@@ -100,7 +101,7 @@ int64 ComputeFilesSize(const FilePath& directory,
//
// WARNING: USING THIS WITH recursive==true IS EQUIVALENT
// TO "rm -rf", SO USE WITH CAUTION.
-bool Delete(const FilePath& path, bool recursive);
+BASE_API bool Delete(const FilePath& path, bool recursive);
#if defined(OS_WIN)
// Schedules to delete the given path, whether it's a file or a directory, until
@@ -108,24 +109,24 @@ bool Delete(const FilePath& path, bool recursive);
// Note:
// 1) The file/directory to be deleted should exist in a temp folder.
// 2) The directory to be deleted must be empty.
-bool DeleteAfterReboot(const FilePath& path);
+BASE_API bool DeleteAfterReboot(const FilePath& path);
#endif
// Moves the given path, whether it's a file or a directory.
// If a simple rename is not possible, such as in the case where the paths are
// on different volumes, this will attempt to copy and delete. Returns
// true for success.
-bool Move(const FilePath& from_path, const FilePath& to_path);
+BASE_API bool Move(const FilePath& from_path, const FilePath& to_path);
// Renames file |from_path| to |to_path|. Both paths must be on the same
// volume, or the function will fail. Destination file will be created
// if it doesn't exist. Prefer this function over Move when dealing with
// temporary files. On Windows it preserves attributes of the target file.
// Returns true on success.
-bool ReplaceFile(const FilePath& from_path, const FilePath& to_path);
+BASE_API bool ReplaceFile(const FilePath& from_path, const FilePath& to_path);
// Copies a single file. Use CopyDirectory to copy directories.
-bool CopyFile(const FilePath& from_path, const FilePath& to_path);
+BASE_API bool CopyFile(const FilePath& from_path, const FilePath& to_path);
// Copies the given path, and optionally all subdirectories and their contents
// as well.
@@ -134,45 +135,46 @@ bool CopyFile(const FilePath& from_path, const FilePath& to_path);
// Don't use wildcards on the names, it may stop working without notice.
//
// If you only need to copy a file use CopyFile, it's faster.
-bool CopyDirectory(const FilePath& from_path, const FilePath& to_path,
- bool recursive);
+BASE_API bool CopyDirectory(const FilePath& from_path, const FilePath& to_path,
+ bool recursive);
// Returns true if the given path exists on the local filesystem,
// false otherwise.
-bool PathExists(const FilePath& path);
+BASE_API bool PathExists(const FilePath& path);
// Returns true if the given path is writable by the user, false otherwise.
-bool PathIsWritable(const FilePath& path);
+BASE_API bool PathIsWritable(const FilePath& path);
// Returns true if the given path exists and is a directory, false otherwise.
-bool DirectoryExists(const FilePath& path);
+BASE_API bool DirectoryExists(const FilePath& path);
#if defined(OS_WIN)
// Gets the creation time of the given file (expressed in the local timezone),
// and returns it via the creation_time parameter. Returns true if successful,
// false otherwise.
-bool GetFileCreationLocalTime(const std::wstring& filename,
- LPSYSTEMTIME creation_time);
+BASE_API bool GetFileCreationLocalTime(const std::wstring& filename,
+ LPSYSTEMTIME creation_time);
// Same as above, but takes a previously-opened file handle instead of a name.
-bool GetFileCreationLocalTimeFromHandle(HANDLE file_handle,
- LPSYSTEMTIME creation_time);
+BASE_API bool GetFileCreationLocalTimeFromHandle(HANDLE file_handle,
+ LPSYSTEMTIME creation_time);
#endif // defined(OS_WIN)
// Returns true if the contents of the two files given are equal, false
// otherwise. If either file can't be read, returns false.
-bool ContentsEqual(const FilePath& filename1,
- const FilePath& filename2);
+BASE_API bool ContentsEqual(const FilePath& filename1,
+ const FilePath& filename2);
// Returns true if the contents of the two text files given are equal, false
// otherwise. This routine treats "\r\n" and "\n" as equivalent.
-bool TextContentsEqual(const FilePath& filename1, const FilePath& filename2);
+BASE_API bool TextContentsEqual(const FilePath& filename1,
+ const FilePath& filename2);
// Read the file at |path| into |contents|, returning true on success.
// |contents| may be NULL, in which case this function is useful for its
// side effect of priming the disk cache.
// Useful for unit tests.
-bool ReadFileToString(const FilePath& path, std::string* contents);
+BASE_API bool ReadFileToString(const FilePath& path, std::string* contents);
#if defined(OS_POSIX)
// Read exactly |bytes| bytes from file descriptor |fd|, storing the result
@@ -194,7 +196,7 @@ bool ReadSymbolicLink(const FilePath& symlink, FilePath* target);
// This methods tries to resolve a shortcut .LNK file. If the |path| is valid
// returns true and puts the target into the |path|, otherwise returns
// false leaving the path as it is.
-bool ResolveShortcut(FilePath* path);
+BASE_API bool ResolveShortcut(FilePath* path);
// Create a Windows shortcut (.LNK file)
// This method creates a shortcut link using the information given. Ensure
@@ -205,10 +207,14 @@ bool ResolveShortcut(FilePath* path);
// The 'icon' can specify a dll or exe in which case the icon index is the
// resource id. 'app_id' is the app model id for the shortcut on Win7.
// Note that if the shortcut exists it will overwrite it.
-bool CreateShortcutLink(const wchar_t *source, const wchar_t *destination,
- const wchar_t *working_dir, const wchar_t *arguments,
- const wchar_t *description, const wchar_t *icon,
- int icon_index, const wchar_t* app_id);
+BASE_API bool CreateShortcutLink(const wchar_t *source,
+ const wchar_t *destination,
+ const wchar_t *working_dir,
+ const wchar_t *arguments,
+ const wchar_t *description,
+ const wchar_t *icon,
+ int icon_index,
+ const wchar_t* app_id);
// Update a Windows shortcut (.LNK file). This method assumes the shortcut
// link already exists (otherwise false is returned). Ensure you have
@@ -217,86 +223,92 @@ bool CreateShortcutLink(const wchar_t *source, const wchar_t *destination,
// is NULL no changes are made to the shortcut). 'destination' is the link
// file to be updated. 'app_id' is the app model id for the shortcut on Win7.
// For best results pass the filename with the .lnk extension.
-bool UpdateShortcutLink(const wchar_t *source, const wchar_t *destination,
- const wchar_t *working_dir, const wchar_t *arguments,
- const wchar_t *description, const wchar_t *icon,
- int icon_index, const wchar_t* app_id);
+BASE_API bool UpdateShortcutLink(const wchar_t *source,
+ const wchar_t *destination,
+ const wchar_t *working_dir,
+ const wchar_t *arguments,
+ const wchar_t *description,
+ const wchar_t *icon,
+ int icon_index,
+ const wchar_t* app_id);
// Pins a shortcut to the Windows 7 taskbar. The shortcut file must already
// exist and be a shortcut that points to an executable.
-bool TaskbarPinShortcutLink(const wchar_t* shortcut);
+BASE_API bool TaskbarPinShortcutLink(const wchar_t* shortcut);
// Unpins a shortcut from the Windows 7 taskbar. The shortcut must exist and
// already be pinned to the taskbar.
-bool TaskbarUnpinShortcutLink(const wchar_t* shortcut);
+BASE_API bool TaskbarUnpinShortcutLink(const wchar_t* shortcut);
// Copy from_path to to_path recursively and then delete from_path recursively.
// Returns true if all operations succeed.
// This function simulates Move(), but unlike Move() it works across volumes.
// This fuction is not transactional.
-bool CopyAndDeleteDirectory(const FilePath& from_path,
- const FilePath& to_path);
+BASE_API bool CopyAndDeleteDirectory(const FilePath& from_path,
+ const FilePath& to_path);
#endif // defined(OS_WIN)
// Return true if the given directory is empty
-bool IsDirectoryEmpty(const FilePath& dir_path);
+BASE_API bool IsDirectoryEmpty(const FilePath& dir_path);
// Get the temporary directory provided by the system.
// WARNING: DON'T USE THIS. If you want to create a temporary file, use one of
// the functions below.
-bool GetTempDir(FilePath* path);
+BASE_API bool GetTempDir(FilePath* path);
// Get a temporary directory for shared memory files.
// Only useful on POSIX; redirects to GetTempDir() on Windows.
-bool GetShmemTempDir(FilePath* path);
+BASE_API bool GetShmemTempDir(FilePath* path);
// Get the home directory. This is more complicated than just getenv("HOME")
// as it knows to fall back on getpwent() etc.
-FilePath GetHomeDir();
+BASE_API FilePath GetHomeDir();
// Creates a temporary file. The full path is placed in |path|, and the
// function returns true if was successful in creating the file. The file will
// be empty and all handles closed after this function returns.
-bool CreateTemporaryFile(FilePath* path);
+BASE_API bool CreateTemporaryFile(FilePath* path);
// Same as CreateTemporaryFile but the file is created in |dir|.
-bool CreateTemporaryFileInDir(const FilePath& dir, FilePath* temp_file);
+BASE_API bool CreateTemporaryFileInDir(const FilePath& dir,
+ FilePath* temp_file);
// Create and open a temporary file. File is opened for read/write.
// The full path is placed in |path|.
// Returns a handle to the opened file or NULL if an error occured.
-FILE* CreateAndOpenTemporaryFile(FilePath* path);
+BASE_API FILE* CreateAndOpenTemporaryFile(FilePath* path);
// Like above but for shmem files. Only useful for POSIX.
-FILE* CreateAndOpenTemporaryShmemFile(FilePath* path);
+BASE_API FILE* CreateAndOpenTemporaryShmemFile(FilePath* path);
// Similar to CreateAndOpenTemporaryFile, but the file is created in |dir|.
-FILE* CreateAndOpenTemporaryFileInDir(const FilePath& dir, FilePath* path);
+BASE_API FILE* CreateAndOpenTemporaryFileInDir(const FilePath& dir,
+ FilePath* path);
// Create a new directory. If prefix is provided, the new directory name is in
// the format of prefixyyyy.
// NOTE: prefix is ignored in the POSIX implementation.
// If success, return true and output the full path of the directory created.
-bool CreateNewTempDirectory(const FilePath::StringType& prefix,
- FilePath* new_temp_path);
+BASE_API bool CreateNewTempDirectory(const FilePath::StringType& prefix,
+ FilePath* new_temp_path);
// Create a directory within another directory.
// Extra characters will be appended to |prefix| to ensure that the
// new directory does not have the same name as an existing directory.
-bool CreateTemporaryDirInDir(const FilePath& base_dir,
- const FilePath::StringType& prefix,
- FilePath* new_dir);
+BASE_API bool CreateTemporaryDirInDir(const FilePath& base_dir,
+ const FilePath::StringType& prefix,
+ FilePath* new_dir);
// Creates a directory, as well as creating any parent directories, if they
// don't exist. Returns 'true' on successful creation, or if the directory
// already exists. The directory is only readable by the current user.
-bool CreateDirectory(const FilePath& full_path);
+BASE_API bool CreateDirectory(const FilePath& full_path);
// Returns the file size. Returns true on success.
-bool GetFileSize(const FilePath& file_path, int64* file_size);
+BASE_API bool GetFileSize(const FilePath& file_path, int64* file_size);
// Returns true if the given path's base name is ".".
-bool IsDot(const FilePath& path);
+BASE_API bool IsDot(const FilePath& path);
// Returns true if the given path's base name is "..".
-bool IsDotDot(const FilePath& path);
+BASE_API bool IsDotDot(const FilePath& path);
// Sets |real_path| to |path| with symbolic links and junctions expanded.
// On windows, make sure the path starts with a lettered drive.
@@ -304,27 +316,29 @@ bool IsDotDot(const FilePath& path);
// a directory or to a nonexistent path. On windows, this function will
// fail if |path| is a junction or symlink that points to an empty file,
// or if |real_path| would be longer than MAX_PATH characters.
-bool NormalizeFilePath(const FilePath& path, FilePath* real_path);
+BASE_API bool NormalizeFilePath(const FilePath& path, FilePath* real_path);
#if defined(OS_WIN)
// Given an existing file in |path|, it returns in |real_path| the path
// in the native NT format, of the form "\Device\HarddiskVolumeXX\..".
// Returns false it it fails. Empty files cannot be resolved with this
// function.
-bool NormalizeToNativeFilePath(const FilePath& path, FilePath* nt_path);
+BASE_API bool NormalizeToNativeFilePath(const FilePath& path,
+ FilePath* nt_path);
#endif
// Returns information about the given file path.
-bool GetFileInfo(const FilePath& file_path, base::PlatformFileInfo* info);
+BASE_API bool GetFileInfo(const FilePath& file_path,
+ base::PlatformFileInfo* info);
// Sets the time of the last access and the time of the last modification.
-bool TouchFile(const FilePath& path,
- const base::Time& last_accessed,
- const base::Time& last_modified);
+BASE_API bool TouchFile(const FilePath& path,
+ const base::Time& last_accessed,
+ const base::Time& last_modified);
// Set the time of the last modification. Useful for unit tests.
-bool SetLastModifiedTime(const FilePath& path,
- const base::Time& last_modified);
+BASE_API bool SetLastModifiedTime(const FilePath& path,
+ const base::Time& last_modified);
#if defined(OS_POSIX)
// Store inode number of |path| in |inode|. Return true on success.
@@ -332,32 +346,32 @@ bool GetInode(const FilePath& path, ino_t* inode);
#endif
// Wrapper for fopen-like calls. Returns non-NULL FILE* on success.
-FILE* OpenFile(const FilePath& filename, const char* mode);
+BASE_API FILE* OpenFile(const FilePath& filename, const char* mode);
// Closes file opened by OpenFile. Returns true on success.
-bool CloseFile(FILE* file);
+BASE_API 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);
+BASE_API 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 FilePath& filename, char* data, int size);
+BASE_API int ReadFile(const FilePath& filename, char* data, int size);
// Writes the given buffer into the file, overwriting any data that was
// previously there. Returns the number of bytes written, or -1 on error.
-int WriteFile(const FilePath& filename, const char* data, int size);
+BASE_API int WriteFile(const FilePath& filename, const char* data, int size);
#if defined(OS_POSIX)
// Append the data to |fd|. Does not close |fd| when done.
int WriteFileDescriptor(const int fd, const char* data, int size);
#endif
// Gets the current working directory for the process.
-bool GetCurrentDirectory(FilePath* path);
+BASE_API bool GetCurrentDirectory(FilePath* path);
// Sets the current working directory for the process.
-bool SetCurrentDirectory(const FilePath& path);
+BASE_API bool SetCurrentDirectory(const FilePath& path);
// A class to handle auto-closing of FILE*'s.
class ScopedFILEClose {
@@ -391,7 +405,7 @@ typedef scoped_ptr_malloc<int, ScopedFDClose> ScopedFD;
//
// DO NOT USE FROM THE MAIN THREAD of your application unless it is a test
// program where latency does not matter. This class is blocking.
-class FileEnumerator {
+class BASE_API FileEnumerator {
public:
#if defined(OS_WIN)
typedef WIN32_FIND_DATA FindInfo;
@@ -490,7 +504,7 @@ class FileEnumerator {
DISALLOW_COPY_AND_ASSIGN(FileEnumerator);
};
-class MemoryMappedFile {
+class BASE_API MemoryMappedFile {
public:
// The default constructor sets all members to invalid/null values.
MemoryMappedFile();
@@ -545,13 +559,14 @@ class MemoryMappedFile {
// Renames a file using the SHFileOperation API to ensure that the target file
// gets the correct default security descriptor in the new path.
-bool RenameFileAndResetSecurityDescriptor(
+BASE_API bool RenameFileAndResetSecurityDescriptor(
const FilePath& source_file_path,
const FilePath& target_file_path);
// Returns whether the file has been modified since a particular date.
-bool HasFileBeenModifiedSince(const FileEnumerator::FindInfo& find_info,
- const base::Time& cutoff_time);
+BASE_API bool HasFileBeenModifiedSince(
+ const FileEnumerator::FindInfo& find_info,
+ const base::Time& cutoff_time);
#ifdef UNIT_TEST
@@ -611,8 +626,8 @@ inline bool MakeFileUnreadable(const FilePath& path) {
// is passed in. If it is 0 then the whole file is paged in. The step size
// which indicates the number of bytes to skip after every page touched is
// also passed in.
-bool PreReadImage(const wchar_t* file_path, size_t size_to_read,
- size_t step_size);
+bool BASE_API PreReadImage(const wchar_t* file_path, size_t size_to_read,
+ size_t step_size);
#endif // OS_WIN
#if defined(OS_LINUX)
@@ -625,6 +640,7 @@ enum FileSystemType {
FILE_SYSTEM_SMB,
FILE_SYSTEM_CODA,
FILE_SYSTEM_MEMORY, // in-memory file system
+ FILE_SYSTEM_CGROUP, // cgroup control.
FILE_SYSTEM_OTHER, // any other value.
FILE_SYSTEM_TYPE_COUNT
};
diff --git a/base/file_util_deprecated.h b/base/file_util_deprecated.h
index dac4b45..d24e54d 100644
--- a/base/file_util_deprecated.h
+++ b/base/file_util_deprecated.h
@@ -14,6 +14,7 @@
#define BASE_FILE_UTIL_DEPRECATED_H_
#pragma once
+#include "base/base_api.h"
#include "build/build_config.h"
// We've successfully deprecated all of these functions on non-Windows
@@ -24,22 +25,24 @@
namespace file_util {
// Use the FilePath versions instead.
-FILE* OpenFile(const std::string& filename, const char* mode);
-FILE* OpenFile(const std::wstring& filename, const char* mode);
+BASE_API FILE* OpenFile(const std::string& filename, const char* mode);
+BASE_API FILE* OpenFile(const std::wstring& filename, const char* mode);
// Appends new_ending to path, adding a separator between the two if necessary.
-void AppendToPath(std::wstring* path, const std::wstring& new_ending);
+BASE_API void AppendToPath(std::wstring* path, const std::wstring& new_ending);
// Use FilePath::Extension instead.
-FilePath::StringType GetFileExtensionFromPath(const FilePath& path);
-std::wstring GetFileExtensionFromPath(const std::wstring& path);
+BASE_API FilePath::StringType GetFileExtensionFromPath(const FilePath& path);
+BASE_API std::wstring GetFileExtensionFromPath(const std::wstring& path);
// Use version that takes a FilePath.
-bool Delete(const std::wstring& path, bool recursive);
-bool CopyDirectory(const std::wstring& from_path, const std::wstring& to_path,
- bool recursive);
-int ReadFile(const std::wstring& filename, char* data, int size);
-int WriteFile(const std::wstring& filename, const char* data, int size);
+BASE_API bool Delete(const std::wstring& path, bool recursive);
+BASE_API bool CopyDirectory(const std::wstring& from_path,
+ const std::wstring& to_path,
+ bool recursive);
+BASE_API int ReadFile(const std::wstring& filename, char* data, int size);
+BASE_API int WriteFile(const std::wstring& filename,
+ const char* data, int size);
}
diff --git a/base/file_util_linux.cc b/base/file_util_linux.cc
index dd0c820..f7d4f6e 100644
--- a/base/file_util_linux.cc
+++ b/base/file_util_linux.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -50,6 +50,9 @@ bool GetFileSystemType(const FilePath& path, FileSystemType* type) {
case 0x01021994: // tmpfs
*type = FILE_SYSTEM_MEMORY;
break;
+ case 0x27e0eb: // CGROUP
+ *type = FILE_SYSTEM_CGROUP;
+ break;
default:
*type = FILE_SYSTEM_OTHER;
}
diff --git a/base/file_util_posix.cc b/base/file_util_posix.cc
index 9a2d90a..34e0938 100644
--- a/base/file_util_posix.cc
+++ b/base/file_util_posix.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -34,8 +34,8 @@
#include "base/eintr_wrapper.h"
#include "base/file_path.h"
#include "base/logging.h"
-#include "base/scoped_ptr.h"
-#include "base/singleton.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/singleton.h"
#include "base/string_util.h"
#include "base/sys_string_conversions.h"
#include "base/threading/thread_restrictions.h"
@@ -407,7 +407,7 @@ int CreateAndOpenFdForTemporaryFile(FilePath directory, FilePath* path) {
// this should be OK since mkstemp just replaces characters in place
char* buffer = const_cast<char*>(tmpdir_string.c_str());
- return mkstemp(buffer);
+ return HANDLE_EINTR(mkstemp(buffer));
}
bool CreateTemporaryFile(FilePath* path) {
@@ -418,7 +418,7 @@ bool CreateTemporaryFile(FilePath* path) {
int fd = CreateAndOpenFdForTemporaryFile(directory, path);
if (fd < 0)
return false;
- close(fd);
+ ignore_result(HANDLE_EINTR(close(fd)));
return true;
}
@@ -435,13 +435,16 @@ FILE* CreateAndOpenTemporaryFileInDir(const FilePath& dir, FilePath* path) {
if (fd < 0)
return NULL;
- return fdopen(fd, "a+");
+ FILE* file = fdopen(fd, "a+");
+ if (!file)
+ ignore_result(HANDLE_EINTR(close(fd)));
+ return file;
}
bool CreateTemporaryFileInDir(const FilePath& dir, FilePath* temp_file) {
base::ThreadRestrictions::AssertIOAllowed(); // For call to close().
int fd = CreateAndOpenFdForTemporaryFile(dir, temp_file);
- return ((fd >= 0) && !close(fd));
+ return ((fd >= 0) && !HANDLE_EINTR(close(fd)));
}
static bool CreateTemporaryDirInDirImpl(const FilePath& base_dir,
@@ -541,12 +544,16 @@ FILE* OpenFile(const std::string& filename, const char* mode) {
FILE* OpenFile(const FilePath& filename, const char* mode) {
base::ThreadRestrictions::AssertIOAllowed();
- return fopen(filename.value().c_str(), mode);
+ FILE* result = NULL;
+ do {
+ result = fopen(filename.value().c_str(), mode);
+ } while (!result && errno == EINTR);
+ return result;
}
int ReadFile(const FilePath& filename, char* data, int size) {
base::ThreadRestrictions::AssertIOAllowed();
- int fd = open(filename.value().c_str(), O_RDONLY);
+ int fd = HANDLE_EINTR(open(filename.value().c_str(), O_RDONLY));
if (fd < 0)
return -1;
@@ -558,7 +565,7 @@ int ReadFile(const FilePath& filename, char* data, int size) {
int WriteFile(const FilePath& filename, const char* data, int size) {
base::ThreadRestrictions::AssertIOAllowed();
- int fd = creat(filename.value().c_str(), 0666);
+ int fd = HANDLE_EINTR(creat(filename.value().c_str(), 0666));
if (fd < 0)
return -1;
@@ -776,7 +783,7 @@ void MemoryMappedFile::CloseHandles() {
if (data_ != NULL)
munmap(data_, length_);
if (file_ != base::kInvalidPlatformFileValue)
- close(file_);
+ ignore_result(HANDLE_EINTR(close(file_)));
data_ = NULL;
length_ = 0;
@@ -842,13 +849,13 @@ FilePath GetHomeDir() {
bool CopyFile(const FilePath& from_path, const FilePath& to_path) {
base::ThreadRestrictions::AssertIOAllowed();
- int infile = open(from_path.value().c_str(), O_RDONLY);
+ int infile = HANDLE_EINTR(open(from_path.value().c_str(), O_RDONLY));
if (infile < 0)
return false;
- int outfile = creat(to_path.value().c_str(), 0666);
+ int outfile = HANDLE_EINTR(creat(to_path.value().c_str(), 0666));
if (outfile < 0) {
- close(infile);
+ ignore_result(HANDLE_EINTR(close(infile)));
return false;
}
diff --git a/base/file_util_proxy.cc b/base/file_util_proxy.cc
index d357e98..1d5b9cc 100644
--- a/base/file_util_proxy.cc
+++ b/base/file_util_proxy.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -570,7 +570,8 @@ class RelayWrite : public MessageLoopRelay {
offset_(offset),
buffer_(new char[bytes_to_write]),
bytes_to_write_(bytes_to_write),
- callback_(callback) {
+ callback_(callback),
+ bytes_written_(0) {
memcpy(buffer_.get(), buffer, bytes_to_write);
}
diff --git a/base/file_util_proxy.h b/base/file_util_proxy.h
index f2368cc..08df57b 100644
--- a/base/file_util_proxy.h
+++ b/base/file_util_proxy.h
@@ -7,11 +7,12 @@
#include <vector>
+#include "base/base_api.h"
#include "base/callback.h"
#include "base/file_path.h"
#include "base/file_util.h"
+#include "base/memory/ref_counted.h"
#include "base/platform_file.h"
-#include "base/ref_counted.h"
#include "base/tracked_objects.h"
namespace base {
@@ -20,7 +21,7 @@ class MessageLoopProxy;
class Time;
// This class provides asynchronous access to common file routines.
-class FileUtilProxy {
+class BASE_API FileUtilProxy {
public:
// Holds metadata for file or directory entry. Used by ReadDirectoryCallback.
struct Entry {
diff --git a/base/file_util_unittest.cc b/base/file_util_unittest.cc
index ea29df5..733f9f1 100644
--- a/base/file_util_unittest.cc
+++ b/base/file_util_unittest.cc
@@ -18,8 +18,8 @@
#include "base/base_paths.h"
#include "base/file_path.h"
#include "base/file_util.h"
+#include "base/memory/scoped_temp_dir.h"
#include "base/path_service.h"
-#include "base/scoped_temp_dir.h"
#include "base/threading/platform_thread.h"
#include "base/time.h"
#include "base/utf_string_conversions.h"
@@ -162,7 +162,7 @@ class FindResultCollector {
// Simple function to dump some text into a new file.
void CreateTextFile(const FilePath& filename,
const std::wstring& contents) {
- std::ofstream file;
+ std::wofstream file;
file.open(filename.value().c_str());
ASSERT_TRUE(file.is_open());
file << contents;
@@ -175,7 +175,7 @@ std::wstring ReadTextFile(const FilePath& filename) {
std::wifstream file;
file.open(filename.value().c_str());
EXPECT_TRUE(file.is_open());
- file.getline(contents, 64);
+ file.getline(contents, arraysize(contents));
file.close();
return std::wstring(contents);
}
diff --git a/base/file_util_win.cc b/base/file_util_win.cc
index 2c26a16..3689614 100644
--- a/base/file_util_win.cc
+++ b/base/file_util_win.cc
@@ -55,7 +55,7 @@ bool DevicePathToDriveLetterPath(const FilePath& device_path,
// For each string in the drive mapping, get the junction that links
// to it. If that junction is a prefix of |device_path|, then we
// know that |drive| is the real path prefix.
- while(*drive_map_ptr) {
+ while (*drive_map_ptr) {
drive[0] = drive_map_ptr[0]; // Copy the drive letter.
if (QueryDosDevice(drive, device_name, MAX_PATH) &&
@@ -66,7 +66,7 @@ bool DevicePathToDriveLetterPath(const FilePath& device_path,
}
// Move to the next drive letter string, which starts one
// increment after the '\0' that terminates the current string.
- while(*drive_map_ptr++);
+ while (*drive_map_ptr++);
}
// No drive matched. The path does not start with a device junction
@@ -104,7 +104,7 @@ int CountFilesCreatedAfter(const FilePath& path,
(wcscmp(find_file_data.cFileName, L".") == 0))
continue;
- long result = CompareFileTime(&find_file_data.ftCreationTime,
+ long result = CompareFileTime(&find_file_data.ftCreationTime, // NOLINT
&comparison_filetime);
// File was created after or on comparison time
if ((result == 1) || (result == 0))
@@ -187,13 +187,26 @@ bool Move(const FilePath& from_path, const FilePath& to_path) {
if (MoveFileEx(from_path.value().c_str(), to_path.value().c_str(),
MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING) != 0)
return true;
+
+ // Keep the last error value from MoveFileEx around in case the below
+ // fails.
+ bool ret = false;
+ DWORD last_error = ::GetLastError();
+
if (DirectoryExists(from_path)) {
// MoveFileEx fails if moving directory across volumes. We will simulate
// the move by using Copy and Delete. Ideally we could check whether
// from_path and to_path are indeed in different volumes.
- return CopyAndDeleteDirectory(from_path, to_path);
+ ret = CopyAndDeleteDirectory(from_path, to_path);
}
- return false;
+
+ if (!ret) {
+ // Leave a clue about what went wrong so that it can be (at least) picked
+ // up by a PLOG entry.
+ ::SetLastError(last_error);
+ }
+
+ return ret;
}
bool ReplaceFile(const FilePath& from_path, const FilePath& to_path) {
@@ -442,7 +455,6 @@ bool CreateShortcutLink(const wchar_t *source, const wchar_t *destination,
return SUCCEEDED(result);
}
-
bool UpdateShortcutLink(const wchar_t *source, const wchar_t *destination,
const wchar_t *working_dir, const wchar_t *arguments,
const wchar_t *description, const wchar_t *icon,
@@ -491,6 +503,16 @@ bool UpdateShortcutLink(const wchar_t *source, const wchar_t *destination,
}
HRESULT result = i_persist_file->Save(destination, TRUE);
+
+ i_persist_file.Release();
+ i_shell_link.Release();
+
+ // If we successfully updated the icon, notify the shell that we have done so.
+ if (SUCCEEDED(result)) {
+ SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST | SHCNF_FLUSHNOWAIT,
+ NULL, NULL);
+ }
+
return SUCCEEDED(result);
}
@@ -921,8 +943,9 @@ FilePath FileEnumerator::Next() {
}
if (file_type_ & FileEnumerator::DIRECTORIES)
return cur_file;
- } else if (file_type_ & FileEnumerator::FILES)
+ } else if (file_type_ & FileEnumerator::FILES) {
return cur_file;
+ }
}
return FilePath();
@@ -972,10 +995,8 @@ bool MemoryMappedFile::MapFileToMemoryInternalEx(int flags) {
if (length_ == INVALID_FILE_SIZE)
return false;
- // length_ value comes from GetFileSize() above. GetFileSize() returns DWORD,
- // therefore the cast here is safe.
file_mapping_ = ::CreateFileMapping(file_, NULL, PAGE_READONLY | flags,
- 0, static_cast<DWORD>(length_), NULL);
+ 0, 0, NULL);
if (!file_mapping_) {
// According to msdn, system error codes are only reserved up to 15999.
// http://msdn.microsoft.com/en-us/library/ms681381(v=VS.85).aspx.
@@ -985,7 +1006,7 @@ bool MemoryMappedFile::MapFileToMemoryInternalEx(int flags) {
}
data_ = static_cast<uint8*>(
- ::MapViewOfFile(file_mapping_, FILE_MAP_READ, 0, 0, length_));
+ ::MapViewOfFile(file_mapping_, FILE_MAP_READ, 0, 0, 0));
if (!data_) {
UMA_HISTOGRAM_ENUMERATION("MemoryMappedFile.MapViewOfFile",
logging::GetLastSystemErrorCode(), 16000);
@@ -1009,7 +1030,7 @@ void MemoryMappedFile::CloseHandles() {
bool HasFileBeenModifiedSince(const FileEnumerator::FindInfo& find_info,
const base::Time& cutoff_time) {
base::ThreadRestrictions::AssertIOAllowed();
- long result = CompareFileTime(&find_info.ftLastWriteTime,
+ long result = CompareFileTime(&find_info.ftLastWriteTime, // NOLINT
&cutoff_time.ToFileTime());
return result == 1 || result == 0;
}
@@ -1052,7 +1073,7 @@ bool NormalizeToNativeFilePath(const FilePath& path, FilePath* nt_path) {
NULL,
PAGE_READONLY,
0,
- 1, // Just one byte. No need to look at the data.
+ 1, // Just one byte. No need to look at the data.
NULL));
if (!file_map_handle)
return false;
diff --git a/base/file_version_info.h b/base/file_version_info.h
index 481e88d..dca4148 100644
--- a/base/file_version_info.h
+++ b/base/file_version_info.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -6,11 +6,11 @@
#define BASE_FILE_VERSION_INFO_H__
#pragma once
-#include "build/build_config.h"
-
#include <string>
+#include "base/base_api.h"
#include "base/string16.h"
+#include "build/build_config.h"
class FilePath;
@@ -24,7 +24,7 @@ class FilePath;
// version returns values from the Info.plist as appropriate. TODO(avi): make
// this a less-obvious Windows-ism.
-class FileVersionInfo {
+class BASE_API FileVersionInfo {
public:
virtual ~FileVersionInfo() {}
#if defined(OS_WIN) || defined(OS_MACOSX)
diff --git a/base/file_version_info_mac.h b/base/file_version_info_mac.h
index d8cb1a6..7c0184a 100644
--- a/base/file_version_info_mac.h
+++ b/base/file_version_info_mac.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -9,7 +9,7 @@
#include <string>
#include "base/file_version_info.h"
-#include "base/scoped_nsobject.h"
+#include "base/memory/scoped_nsobject.h"
#ifdef __OBJC__
@class NSBundle;
diff --git a/base/file_version_info_mac.mm b/base/file_version_info_mac.mm
index bcfd854..293d904 100644
--- a/base/file_version_info_mac.mm
+++ b/base/file_version_info_mac.mm
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -11,7 +11,8 @@
#include "base/mac/mac_util.h"
#include "base/sys_string_conversions.h"
-FileVersionInfoMac::FileVersionInfoMac(NSBundle *bundle) : bundle_(bundle) {
+FileVersionInfoMac::FileVersionInfoMac(NSBundle *bundle)
+ : bundle_([bundle retain]) {
}
FileVersionInfoMac::~FileVersionInfoMac() {}
diff --git a/base/file_version_info_unittest.cc b/base/file_version_info_unittest.cc
index 2b535c7..4184e04 100644
--- a/base/file_version_info_unittest.cc
+++ b/base/file_version_info_unittest.cc
@@ -1,10 +1,10 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
#include "base/file_util.h"
+#include "base/memory/scoped_ptr.h"
#include "base/path_service.h"
-#include "base/scoped_ptr.h"
#include "base/file_version_info.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/base/file_version_info_win.cc b/base/file_version_info_win.cc
index 953caa9..8c6820e 100644
--- a/base/file_version_info_win.cc
+++ b/base/file_version_info_win.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -12,9 +12,6 @@
#include "base/path_service.h"
#include "base/threading/thread_restrictions.h"
-// This has to be last.
-#include <strsafe.h>
-
FileVersionInfoWin::FileVersionInfoWin(void* data, int language, int code_page)
: language_(language), code_page_(code_page) {
base::ThreadRestrictions::AssertIOAllowed();
diff --git a/base/file_version_info_win.h b/base/file_version_info_win.h
index 4a49314..95652b0 100644
--- a/base/file_version_info_win.h
+++ b/base/file_version_info_win.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -8,14 +8,15 @@
#include <string>
+#include "base/base_api.h"
#include "base/basictypes.h"
#include "base/file_version_info.h"
-#include "base/scoped_ptr.h"
+#include "base/memory/scoped_ptr.h"
struct tagVS_FIXEDFILEINFO;
typedef tagVS_FIXEDFILEINFO VS_FIXEDFILEINFO;
-class FileVersionInfoWin : public FileVersionInfo {
+class BASE_API FileVersionInfoWin : public FileVersionInfo {
public:
FileVersionInfoWin(void* data, int language, int code_page);
~FileVersionInfoWin();
diff --git a/base/files/OWNERS b/base/files/OWNERS
new file mode 100644
index 0000000..ef0b156
--- /dev/null
+++ b/base/files/OWNERS
@@ -0,0 +1,3 @@
+# for file_path_watcher*
+mnissler@chromium.org
+dmaclach@chromium.org
diff --git a/base/files/file_path_watcher.cc b/base/files/file_path_watcher.cc
new file mode 100644
index 0000000..7ce64ac
--- /dev/null
+++ b/base/files/file_path_watcher.cc
@@ -0,0 +1,33 @@
+// Copyright (c) 2011 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.
+
+// Cross platform methods for FilePathWatcher. See the various platform
+// specific implementation files, too.
+
+#include "base/files/file_path_watcher.h"
+
+#include "base/logging.h"
+#include "base/message_loop.h"
+
+namespace base {
+namespace files {
+
+FilePathWatcher::~FilePathWatcher() {
+ impl_->Cancel();
+}
+
+bool FilePathWatcher::Watch(const FilePath& path, Delegate* delegate) {
+ DCHECK(path.IsAbsolute());
+ return impl_->Watch(path, delegate);
+}
+
+FilePathWatcher::PlatformDelegate::PlatformDelegate(): cancelled_(false) {
+}
+
+FilePathWatcher::PlatformDelegate::~PlatformDelegate() {
+ DCHECK(is_cancelled());
+}
+
+} // namespace files
+} // namespace base
diff --git a/base/files/file_path_watcher.h b/base/files/file_path_watcher.h
new file mode 100644
index 0000000..2cf95c6
--- /dev/null
+++ b/base/files/file_path_watcher.h
@@ -0,0 +1,128 @@
+// Copyright (c) 2011 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.
+
+// This module provides a way to monitor a file or directory for changes.
+
+#ifndef BASE_FILES_FILE_PATH_WATCHER_H_
+#define BASE_FILES_FILE_PATH_WATCHER_H_
+#pragma once
+
+#include "base/basictypes.h"
+#include "base/file_path.h"
+#include "base/memory/ref_counted.h"
+#include "base/message_loop_proxy.h"
+
+namespace base {
+namespace files {
+
+// This class lets you register interest in changes on a FilePath.
+// The delegate will get called whenever the file or directory referenced by the
+// FilePath is changed, including created or deleted. Due to limitations in the
+// underlying OS APIs, FilePathWatcher has slightly different semantics on OS X
+// than on Windows or Linux. FilePathWatcher on Linux and Windows will detect
+// modifications to files in a watched directory. FilePathWatcher on Mac will
+// detect the creation and deletion of files in a watched directory, but will
+// not detect modifications to those files. See file_path_watcher_mac.cc for
+// details.
+class FilePathWatcher {
+ public:
+ // Declares the callback client code implements to receive notifications. Note
+ // that implementations of this interface should not keep a reference to the
+ // corresponding FileWatcher object to prevent a reference cycle.
+ class Delegate : public base::RefCountedThreadSafe<Delegate> {
+ public:
+ virtual ~Delegate() {}
+ virtual void OnFilePathChanged(const FilePath& path) = 0;
+ // Called when platform specific code detected an error. The watcher will
+ // not call OnFilePathChanged for future changes.
+ virtual void OnFilePathError(const FilePath& path) {}
+ };
+
+ FilePathWatcher();
+ ~FilePathWatcher();
+
+ // Register interest in any changes on |path|. OnPathChanged will be called
+ // back for each change. Returns true on success.
+ // OnFilePathChanged() will be called on the same thread as Watch() is called,
+ // which should have a MessageLoop of TYPE_IO.
+ bool Watch(const FilePath& path, Delegate* delegate) WARN_UNUSED_RESULT;
+
+ class PlatformDelegate;
+
+ // A custom Task that always cleans up the PlatformDelegate, either when
+ // executed or when deleted without having been executed at all, as can
+ // happen during shutdown.
+ class CancelTask : public Task {
+ public:
+ CancelTask(PlatformDelegate* delegate): delegate_(delegate) {}
+ virtual ~CancelTask() {
+ delegate_->CancelOnMessageLoopThread();
+ }
+
+ virtual void Run() {
+ delegate_->CancelOnMessageLoopThread();
+ }
+ private:
+ scoped_refptr<PlatformDelegate> delegate_;
+
+ DISALLOW_COPY_AND_ASSIGN(CancelTask);
+ };
+
+ // Used internally to encapsulate different members on different platforms.
+ class PlatformDelegate : public base::RefCountedThreadSafe<PlatformDelegate> {
+ public:
+ PlatformDelegate();
+
+ // Start watching for the given |path| and notify |delegate| about changes.
+ virtual bool Watch(const FilePath& path,
+ Delegate* delegate) WARN_UNUSED_RESULT = 0;
+
+ // Stop watching. This is called from FilePathWatcher's dtor in order to
+ // allow to shut down properly while the object is still alive.
+ // It can be called from any thread.
+ virtual void Cancel() = 0;
+
+ protected:
+ virtual ~PlatformDelegate();
+
+ // Stop watching. This is only called on the thread of the appropriate
+ // message loop. Since it can also be called more than once, it should
+ // check |is_cancelled()| to avoid duplicate work.
+ virtual void CancelOnMessageLoopThread() = 0;
+
+ scoped_refptr<base::MessageLoopProxy> message_loop() const {
+ return message_loop_;
+ }
+
+ void set_message_loop(base::MessageLoopProxy* loop) {
+ message_loop_ = loop;
+ }
+
+ // Must be called before the PlatformDelegate is deleted.
+ void set_cancelled() {
+ cancelled_ = true;
+ }
+
+ bool is_cancelled() const {
+ return cancelled_;
+ }
+
+ private:
+ friend class base::RefCountedThreadSafe<PlatformDelegate>;
+ friend class CancelTask;
+
+ scoped_refptr<base::MessageLoopProxy> message_loop_;
+ bool cancelled_;
+ };
+
+ private:
+ scoped_refptr<PlatformDelegate> impl_;
+
+ DISALLOW_COPY_AND_ASSIGN(FilePathWatcher);
+};
+
+} // namespace files
+} // namespace base
+
+#endif // BASE_FILES_FILE_PATH_WATCHER_H_
diff --git a/base/files/file_path_watcher_browsertest.cc b/base/files/file_path_watcher_browsertest.cc
new file mode 100644
index 0000000..d623c90
--- /dev/null
+++ b/base/files/file_path_watcher_browsertest.cc
@@ -0,0 +1,622 @@
+// Copyright (c) 2011 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.
+
+#include "base/files/file_path_watcher.h"
+
+#include <set>
+
+#if defined(OS_WIN)
+#include <windows.h>
+#include <aclapi.h>
+#elif defined(OS_POSIX)
+#include <sys/stat.h>
+#endif
+
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "base/file_path.h"
+#include "base/file_util.h"
+#include "base/memory/scoped_temp_dir.h"
+#include "base/message_loop.h"
+#include "base/message_loop_proxy.h"
+#include "base/path_service.h"
+#include "base/string_util.h"
+#include "base/stl_util-inl.h"
+#include "base/synchronization/waitable_event.h"
+#include "base/test/test_timeouts.h"
+#include "base/threading/thread.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace base {
+namespace files {
+
+namespace {
+
+class TestDelegate;
+
+// Aggregates notifications from the test delegates and breaks the message loop
+// the test thread is waiting on once they all came in.
+class NotificationCollector
+ : public base::RefCountedThreadSafe<NotificationCollector> {
+ public:
+ NotificationCollector()
+ : loop_(base::MessageLoopProxy::CreateForCurrentThread()) {}
+
+ // Called from the file thread by the delegates.
+ void OnChange(TestDelegate* delegate) {
+ loop_->PostTask(FROM_HERE,
+ NewRunnableMethod(this,
+ &NotificationCollector::RecordChange,
+ make_scoped_refptr(delegate)));
+ }
+
+ void Register(TestDelegate* delegate) {
+ delegates_.insert(delegate);
+ }
+
+ void Reset() {
+ signaled_.clear();
+ }
+
+ bool Success() {
+ return signaled_ == delegates_;
+ }
+
+ private:
+ void RecordChange(TestDelegate* delegate) {
+ ASSERT_TRUE(loop_->BelongsToCurrentThread());
+ ASSERT_TRUE(delegates_.count(delegate));
+ signaled_.insert(delegate);
+
+ // Check whether all delegates have been signaled.
+ if (signaled_ == delegates_)
+ loop_->PostTask(FROM_HERE, new MessageLoop::QuitTask());
+ }
+
+ // Set of registered delegates.
+ std::set<TestDelegate*> delegates_;
+
+ // Set of signaled delegates.
+ std::set<TestDelegate*> signaled_;
+
+ // The loop we should break after all delegates signaled.
+ scoped_refptr<base::MessageLoopProxy> loop_;
+};
+
+// A mock FilePathWatcher::Delegate for testing. I'd rather use gmock, but it's
+// not thread safe for setting expectations, so the test code couldn't safely
+// reset expectations while the file watcher is running. In order to allow this,
+// we keep simple thread safe status flags in TestDelegate.
+class TestDelegate : public FilePathWatcher::Delegate {
+ public:
+ // The message loop specified by |loop| will be quit if a notification is
+ // received while the delegate is |armed_|. Note that the testing code must
+ // guarantee |loop| outlives the file thread on which OnFilePathChanged runs.
+ explicit TestDelegate(NotificationCollector* collector)
+ : collector_(collector) {
+ collector_->Register(this);
+ }
+
+ virtual void OnFilePathChanged(const FilePath&) {
+ collector_->OnChange(this);
+ }
+
+ virtual void OnFilePathError(const FilePath& path) {
+ ADD_FAILURE() << "Error " << path.value();
+ }
+
+ private:
+ scoped_refptr<NotificationCollector> collector_;
+
+ DISALLOW_COPY_AND_ASSIGN(TestDelegate);
+};
+
+// A helper class for setting up watches on the file thread.
+class SetupWatchTask : public Task {
+ public:
+ SetupWatchTask(const FilePath& target,
+ FilePathWatcher* watcher,
+ FilePathWatcher::Delegate* delegate,
+ bool* result,
+ base::WaitableEvent* completion)
+ : target_(target),
+ watcher_(watcher),
+ delegate_(delegate),
+ result_(result),
+ completion_(completion) {}
+
+ void Run() {
+ *result_ = watcher_->Watch(target_, delegate_);
+ completion_->Signal();
+ }
+
+ private:
+ const FilePath target_;
+ FilePathWatcher* watcher_;
+ FilePathWatcher::Delegate* delegate_;
+ bool* result_;
+ base::WaitableEvent* completion_;
+
+ DISALLOW_COPY_AND_ASSIGN(SetupWatchTask);
+};
+
+class FilePathWatcherTest : public testing::Test {
+ public:
+ FilePathWatcherTest()
+ : file_thread_("FilePathWatcherTest") {}
+
+ virtual ~FilePathWatcherTest() {}
+
+ protected:
+ virtual void SetUp() {
+ // Create a separate file thread in order to test proper thread usage.
+ base::Thread::Options options(MessageLoop::TYPE_IO, 0);
+ ASSERT_TRUE(file_thread_.StartWithOptions(options));
+ ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
+ collector_ = new NotificationCollector();
+ }
+
+ virtual void TearDown() {
+ loop_.RunAllPending();
+ }
+
+ FilePath test_file() {
+ return temp_dir_.path().AppendASCII("FilePathWatcherTest");
+ }
+
+ // Write |content| to |file|. Returns true on success.
+ bool WriteFile(const FilePath& file, const std::string& content) {
+ int write_size = file_util::WriteFile(file, content.c_str(),
+ content.length());
+ return write_size == static_cast<int>(content.length());
+ }
+
+ bool SetupWatch(const FilePath& target,
+ FilePathWatcher* watcher,
+ FilePathWatcher::Delegate* delegate) WARN_UNUSED_RESULT {
+ base::WaitableEvent completion(false, false);
+ bool result;
+ file_thread_.message_loop_proxy()->PostTask(FROM_HERE,
+ new SetupWatchTask(target,
+ watcher,
+ delegate,
+ &result,
+ &completion));
+ completion.Wait();
+ return result;
+ }
+
+ bool WaitForEvents() WARN_UNUSED_RESULT {
+ collector_->Reset();
+ loop_.Run();
+ return collector_->Success();
+ }
+
+ NotificationCollector* collector() { return collector_.get(); }
+
+ MessageLoop loop_;
+ base::Thread file_thread_;
+ ScopedTempDir temp_dir_;
+ scoped_refptr<NotificationCollector> collector_;
+};
+
+// Basic test: Create the file and verify that we notice.
+TEST_F(FilePathWatcherTest, NewFile) {
+ FilePathWatcher watcher;
+ scoped_refptr<TestDelegate> delegate(new TestDelegate(collector()));
+ ASSERT_TRUE(SetupWatch(test_file(), &watcher, delegate.get()));
+
+ ASSERT_TRUE(WriteFile(test_file(), "content"));
+ ASSERT_TRUE(WaitForEvents());
+}
+
+// Verify that modifying the file is caught.
+TEST_F(FilePathWatcherTest, ModifiedFile) {
+ ASSERT_TRUE(WriteFile(test_file(), "content"));
+
+ FilePathWatcher watcher;
+ scoped_refptr<TestDelegate> delegate(new TestDelegate(collector()));
+ ASSERT_TRUE(SetupWatch(test_file(), &watcher, delegate.get()));
+
+ // Now make sure we get notified if the file is modified.
+ ASSERT_TRUE(WriteFile(test_file(), "new content"));
+ ASSERT_TRUE(WaitForEvents());
+}
+
+// Verify that moving the file into place is caught.
+TEST_F(FilePathWatcherTest, MovedFile) {
+ FilePath source_file(temp_dir_.path().AppendASCII("source"));
+ ASSERT_TRUE(WriteFile(source_file, "content"));
+
+ FilePathWatcher watcher;
+ scoped_refptr<TestDelegate> delegate(new TestDelegate(collector()));
+ ASSERT_TRUE(SetupWatch(test_file(), &watcher, delegate.get()));
+
+ // Now make sure we get notified if the file is modified.
+ ASSERT_TRUE(file_util::Move(source_file, test_file()));
+ ASSERT_TRUE(WaitForEvents());
+}
+
+TEST_F(FilePathWatcherTest, DeletedFile) {
+ ASSERT_TRUE(WriteFile(test_file(), "content"));
+
+ FilePathWatcher watcher;
+ scoped_refptr<TestDelegate> delegate(new TestDelegate(collector()));
+ ASSERT_TRUE(SetupWatch(test_file(), &watcher, delegate.get()));
+
+ // Now make sure we get notified if the file is deleted.
+ file_util::Delete(test_file(), false);
+ ASSERT_TRUE(WaitForEvents());
+}
+
+// Used by the DeleteDuringNotify test below.
+// Deletes the FilePathWatcher when it's notified.
+class Deleter : public FilePathWatcher::Delegate {
+ public:
+ Deleter(FilePathWatcher* watcher, MessageLoop* loop)
+ : watcher_(watcher),
+ loop_(loop) {
+ }
+
+ virtual void OnFilePathChanged(const FilePath& path) {
+ watcher_.reset();
+ loop_->PostTask(FROM_HERE, new MessageLoop::QuitTask());
+ }
+
+ scoped_ptr<FilePathWatcher> watcher_;
+ MessageLoop* loop_;
+};
+
+// Verify that deleting a watcher during the callback doesn't crash.
+TEST_F(FilePathWatcherTest, DeleteDuringNotify) {
+ FilePathWatcher* watcher = new FilePathWatcher;
+ // Takes ownership of watcher.
+ scoped_refptr<Deleter> deleter(new Deleter(watcher, &loop_));
+ ASSERT_TRUE(SetupWatch(test_file(), watcher, deleter.get()));
+
+ ASSERT_TRUE(WriteFile(test_file(), "content"));
+ ASSERT_TRUE(WaitForEvents());
+
+ // We win if we haven't crashed yet.
+ // Might as well double-check it got deleted, too.
+ ASSERT_TRUE(deleter->watcher_.get() == NULL);
+}
+
+// Verify that deleting the watcher works even if there is a pending
+// notification.
+TEST_F(FilePathWatcherTest, DestroyWithPendingNotification) {
+ scoped_refptr<TestDelegate> delegate(new TestDelegate(collector()));
+ FilePathWatcher* watcher = new FilePathWatcher;
+ ASSERT_TRUE(SetupWatch(test_file(), watcher, delegate.get()));
+ ASSERT_TRUE(WriteFile(test_file(), "content"));
+ file_thread_.message_loop_proxy()->DeleteSoon(FROM_HERE, watcher);
+}
+
+TEST_F(FilePathWatcherTest, MultipleWatchersSingleFile) {
+ FilePathWatcher watcher1, watcher2;
+ scoped_refptr<TestDelegate> delegate1(new TestDelegate(collector()));
+ scoped_refptr<TestDelegate> delegate2(new TestDelegate(collector()));
+ ASSERT_TRUE(SetupWatch(test_file(), &watcher1, delegate1.get()));
+ ASSERT_TRUE(SetupWatch(test_file(), &watcher2, delegate2.get()));
+
+ ASSERT_TRUE(WriteFile(test_file(), "content"));
+ ASSERT_TRUE(WaitForEvents());
+}
+
+// Verify that watching a file whose parent directory doesn't exist yet works if
+// the directory and file are created eventually.
+TEST_F(FilePathWatcherTest, NonExistentDirectory) {
+ FilePathWatcher watcher;
+ FilePath dir(temp_dir_.path().AppendASCII("dir"));
+ FilePath file(dir.AppendASCII("file"));
+ scoped_refptr<TestDelegate> delegate(new TestDelegate(collector()));
+ ASSERT_TRUE(SetupWatch(file, &watcher, delegate.get()));
+
+ ASSERT_TRUE(file_util::CreateDirectory(dir));
+
+ ASSERT_TRUE(WriteFile(file, "content"));
+
+ VLOG(1) << "Waiting for file creation";
+ ASSERT_TRUE(WaitForEvents());
+
+ ASSERT_TRUE(WriteFile(file, "content v2"));
+ VLOG(1) << "Waiting for file change";
+ ASSERT_TRUE(WaitForEvents());
+
+ ASSERT_TRUE(file_util::Delete(file, false));
+ VLOG(1) << "Waiting for file deletion";
+ ASSERT_TRUE(WaitForEvents());
+}
+
+// Exercises watch reconfiguration for the case that directories on the path
+// are rapidly created.
+TEST_F(FilePathWatcherTest, DirectoryChain) {
+ FilePath path(temp_dir_.path());
+ std::vector<std::string> dir_names;
+ for (int i = 0; i < 20; i++) {
+ std::string dir(StringPrintf("d%d", i));
+ dir_names.push_back(dir);
+ path = path.AppendASCII(dir);
+ }
+
+ FilePathWatcher watcher;
+ FilePath file(path.AppendASCII("file"));
+ scoped_refptr<TestDelegate> delegate(new TestDelegate(collector()));
+ ASSERT_TRUE(SetupWatch(file, &watcher, delegate.get()));
+
+ FilePath sub_path(temp_dir_.path());
+ for (std::vector<std::string>::const_iterator d(dir_names.begin());
+ d != dir_names.end(); ++d) {
+ sub_path = sub_path.AppendASCII(*d);
+ ASSERT_TRUE(file_util::CreateDirectory(sub_path));
+ }
+ VLOG(1) << "Create File";
+ ASSERT_TRUE(WriteFile(file, "content"));
+ VLOG(1) << "Waiting for file creation";
+ ASSERT_TRUE(WaitForEvents());
+
+ ASSERT_TRUE(WriteFile(file, "content v2"));
+ VLOG(1) << "Waiting for file modification";
+ ASSERT_TRUE(WaitForEvents());
+}
+
+TEST_F(FilePathWatcherTest, DisappearingDirectory) {
+ FilePathWatcher watcher;
+ FilePath dir(temp_dir_.path().AppendASCII("dir"));
+ FilePath file(dir.AppendASCII("file"));
+ ASSERT_TRUE(file_util::CreateDirectory(dir));
+ ASSERT_TRUE(WriteFile(file, "content"));
+ scoped_refptr<TestDelegate> delegate(new TestDelegate(collector()));
+ ASSERT_TRUE(SetupWatch(file, &watcher, delegate.get()));
+
+ ASSERT_TRUE(file_util::Delete(dir, true));
+ ASSERT_TRUE(WaitForEvents());
+}
+
+// Tests that a file that is deleted and reappears is tracked correctly.
+TEST_F(FilePathWatcherTest, DeleteAndRecreate) {
+ ASSERT_TRUE(WriteFile(test_file(), "content"));
+ FilePathWatcher watcher;
+ scoped_refptr<TestDelegate> delegate(new TestDelegate(collector()));
+ ASSERT_TRUE(SetupWatch(test_file(), &watcher, delegate.get()));
+
+ ASSERT_TRUE(file_util::Delete(test_file(), false));
+ VLOG(1) << "Waiting for file deletion";
+ ASSERT_TRUE(WaitForEvents());
+
+ ASSERT_TRUE(WriteFile(test_file(), "content"));
+ VLOG(1) << "Waiting for file creation";
+ ASSERT_TRUE(WaitForEvents());
+}
+
+TEST_F(FilePathWatcherTest, WatchDirectory) {
+ FilePathWatcher watcher;
+ FilePath dir(temp_dir_.path().AppendASCII("dir"));
+ FilePath file1(dir.AppendASCII("file1"));
+ FilePath file2(dir.AppendASCII("file2"));
+ scoped_refptr<TestDelegate> delegate(new TestDelegate(collector()));
+ ASSERT_TRUE(SetupWatch(dir, &watcher, delegate.get()));
+
+ ASSERT_TRUE(file_util::CreateDirectory(dir));
+ VLOG(1) << "Waiting for directory creation";
+ ASSERT_TRUE(WaitForEvents());
+
+ ASSERT_TRUE(WriteFile(file1, "content"));
+ VLOG(1) << "Waiting for file1 creation";
+ ASSERT_TRUE(WaitForEvents());
+
+#if !defined(OS_MACOSX)
+ // Mac implementation does not detect files modified in a directory.
+ ASSERT_TRUE(WriteFile(file1, "content v2"));
+ VLOG(1) << "Waiting for file1 modification";
+ ASSERT_TRUE(WaitForEvents());
+#endif // !OS_MACOSX
+
+ ASSERT_TRUE(file_util::Delete(file1, false));
+ VLOG(1) << "Waiting for file1 deletion";
+ ASSERT_TRUE(WaitForEvents());
+
+ ASSERT_TRUE(WriteFile(file2, "content"));
+ VLOG(1) << "Waiting for file2 creation";
+ ASSERT_TRUE(WaitForEvents());
+}
+
+TEST_F(FilePathWatcherTest, MoveParent) {
+ FilePathWatcher file_watcher;
+ FilePathWatcher subdir_watcher;
+ FilePath dir(temp_dir_.path().AppendASCII("dir"));
+ FilePath dest(temp_dir_.path().AppendASCII("dest"));
+ FilePath subdir(dir.AppendASCII("subdir"));
+ FilePath file(subdir.AppendASCII("file"));
+ scoped_refptr<TestDelegate> file_delegate(new TestDelegate(collector()));
+ ASSERT_TRUE(SetupWatch(file, &file_watcher, file_delegate.get()));
+ scoped_refptr<TestDelegate> subdir_delegate(new TestDelegate(collector()));
+ ASSERT_TRUE(SetupWatch(subdir, &subdir_watcher, subdir_delegate.get()));
+
+ // Setup a directory hierarchy.
+ ASSERT_TRUE(file_util::CreateDirectory(subdir));
+ ASSERT_TRUE(WriteFile(file, "content"));
+ VLOG(1) << "Waiting for file creation";
+ ASSERT_TRUE(WaitForEvents());
+
+ // Move the parent directory.
+ file_util::Move(dir, dest);
+ VLOG(1) << "Waiting for directory move";
+ ASSERT_TRUE(WaitForEvents());
+}
+
+TEST_F(FilePathWatcherTest, MoveChild) {
+ FilePathWatcher file_watcher;
+ FilePathWatcher subdir_watcher;
+ FilePath source_dir(temp_dir_.path().AppendASCII("source"));
+ FilePath source_subdir(source_dir.AppendASCII("subdir"));
+ FilePath source_file(source_subdir.AppendASCII("file"));
+ FilePath dest_dir(temp_dir_.path().AppendASCII("dest"));
+ FilePath dest_subdir(dest_dir.AppendASCII("subdir"));
+ FilePath dest_file(dest_subdir.AppendASCII("file"));
+
+ // Setup a directory hierarchy.
+ ASSERT_TRUE(file_util::CreateDirectory(source_subdir));
+ ASSERT_TRUE(WriteFile(source_file, "content"));
+
+ scoped_refptr<TestDelegate> file_delegate(new TestDelegate(collector()));
+ ASSERT_TRUE(SetupWatch(dest_file, &file_watcher, file_delegate.get()));
+ scoped_refptr<TestDelegate> subdir_delegate(new TestDelegate(collector()));
+ ASSERT_TRUE(SetupWatch(dest_subdir, &subdir_watcher, subdir_delegate.get()));
+
+ // Move the directory into place, s.t. the watched file appears.
+ ASSERT_TRUE(file_util::Move(source_dir, dest_dir));
+ ASSERT_TRUE(WaitForEvents());
+}
+
+#if !defined(OS_LINUX)
+// Linux implementation of FilePathWatcher doesn't catch attribute changes.
+// http://crbug.com/78043
+
+// Verify that changing attributes on a file is caught
+TEST_F(FilePathWatcherTest, FileAttributesChanged) {
+ ASSERT_TRUE(WriteFile(test_file(), "content"));
+ FilePathWatcher watcher;
+ scoped_refptr<TestDelegate> delegate(new TestDelegate(collector()));
+ ASSERT_TRUE(SetupWatch(test_file(), &watcher, delegate.get()));
+
+ // Now make sure we get notified if the file is modified.
+ ASSERT_TRUE(file_util::MakeFileUnreadable(test_file()));
+ ASSERT_TRUE(WaitForEvents());
+}
+
+#endif // !OS_LINUX
+
+enum Permission {
+ Read,
+ Write,
+ Execute
+};
+
+bool ChangeFilePermissions(const FilePath& path, Permission perm, bool allow) {
+#if defined(OS_POSIX)
+ struct stat stat_buf;
+
+ if (stat(path.value().c_str(), &stat_buf) != 0)
+ return false;
+
+ mode_t mode = 0;
+ switch (perm) {
+ case Read:
+ mode = S_IRUSR | S_IRGRP | S_IROTH;
+ break;
+ case Write:
+ mode = S_IWUSR | S_IWGRP | S_IWOTH;
+ break;
+ case Execute:
+ mode = S_IXUSR | S_IXGRP | S_IXOTH;
+ break;
+ default:
+ ADD_FAILURE() << "unknown perm " << perm;
+ return false;
+ }
+ if (allow) {
+ stat_buf.st_mode |= mode;
+ } else {
+ stat_buf.st_mode &= ~mode;
+ }
+ return chmod(path.value().c_str(), stat_buf.st_mode) == 0;
+
+#elif defined(OS_WIN)
+ PACL old_dacl;
+ PSECURITY_DESCRIPTOR security_descriptor;
+ if (GetNamedSecurityInfo(const_cast<wchar_t*>(path.value().c_str()),
+ SE_FILE_OBJECT,
+ DACL_SECURITY_INFORMATION, NULL, NULL, &old_dacl,
+ NULL, &security_descriptor) != ERROR_SUCCESS)
+ return false;
+
+ DWORD mode = 0;
+ switch (perm) {
+ case Read:
+ mode = GENERIC_READ;
+ break;
+ case Write:
+ mode = GENERIC_WRITE;
+ break;
+ case Execute:
+ mode = GENERIC_EXECUTE;
+ break;
+ default:
+ ADD_FAILURE() << "unknown perm " << perm;
+ return false;
+ }
+
+ // Deny Read access for the current user.
+ EXPLICIT_ACCESS change;
+ change.grfAccessPermissions = mode;
+ change.grfAccessMode = allow ? GRANT_ACCESS : DENY_ACCESS;
+ change.grfInheritance = 0;
+ change.Trustee.pMultipleTrustee = NULL;
+ change.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
+ change.Trustee.TrusteeForm = TRUSTEE_IS_NAME;
+ change.Trustee.TrusteeType = TRUSTEE_IS_USER;
+ change.Trustee.ptstrName = L"CURRENT_USER";
+
+ PACL new_dacl;
+ if (SetEntriesInAcl(1, &change, old_dacl, &new_dacl) != ERROR_SUCCESS) {
+ LocalFree(security_descriptor);
+ return false;
+ }
+
+ DWORD rc = SetNamedSecurityInfo(const_cast<wchar_t*>(path.value().c_str()),
+ SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
+ NULL, NULL, new_dacl, NULL);
+ LocalFree(security_descriptor);
+ LocalFree(new_dacl);
+
+ return rc == ERROR_SUCCESS;
+#else
+ NOTIMPLEMENTED();
+ return false;
+#endif
+}
+
+#if defined(OS_MACOSX)
+// Linux implementation of FilePathWatcher doesn't catch attribute changes.
+// http://crbug.com/78043
+// Windows implementation of FilePathWatcher catches attribute changes that
+// don't affect the path being watched.
+// http://crbug.com/78045
+
+// Verify that changing attributes on a directory works.
+TEST_F(FilePathWatcherTest, DirAttributesChanged) {
+ FilePath test_dir1(temp_dir_.path().AppendASCII("DirAttributesChangedDir1"));
+ FilePath test_dir2(test_dir1.AppendASCII("DirAttributesChangedDir2"));
+ FilePath test_file(test_dir2.AppendASCII("DirAttributesChangedFile"));
+ // Setup a directory hierarchy.
+ ASSERT_TRUE(file_util::CreateDirectory(test_dir1));
+ ASSERT_TRUE(file_util::CreateDirectory(test_dir2));
+ ASSERT_TRUE(WriteFile(test_file, "content"));
+
+ FilePathWatcher watcher;
+ scoped_refptr<TestDelegate> delegate(new TestDelegate(collector()));
+ ASSERT_TRUE(SetupWatch(test_file, &watcher, delegate.get()));
+
+ // We should not get notified in this case as it hasn't affected our ability
+ // to access the file.
+ ASSERT_TRUE(ChangeFilePermissions(test_dir1, Read, false));
+ loop_.PostDelayedTask(FROM_HERE,
+ new MessageLoop::QuitTask,
+ TestTimeouts::tiny_timeout_ms());
+ ASSERT_FALSE(WaitForEvents());
+ ASSERT_TRUE(ChangeFilePermissions(test_dir1, Read, true));
+
+ // We should get notified in this case because filepathwatcher can no
+ // longer access the file
+ ASSERT_TRUE(ChangeFilePermissions(test_dir1, Execute, false));
+ ASSERT_TRUE(WaitForEvents());
+ ASSERT_TRUE(ChangeFilePermissions(test_dir1, Execute, true));
+}
+
+#endif // OS_MACOSX
+} // namespace
+
+} // namespace files
+} // namespace base
diff --git a/base/files/file_path_watcher_linux.cc b/base/files/file_path_watcher_linux.cc
new file mode 100644
index 0000000..0fb10e4
--- /dev/null
+++ b/base/files/file_path_watcher_linux.cc
@@ -0,0 +1,462 @@
+// Copyright (c) 2011 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.
+
+#include "base/files/file_path_watcher.h"
+
+#include <errno.h>
+#include <string.h>
+#include <sys/inotify.h>
+#include <sys/ioctl.h>
+#include <sys/select.h>
+#include <unistd.h>
+
+#include <algorithm>
+#include <set>
+#include <utility>
+#include <vector>
+
+#include "base/eintr_wrapper.h"
+#include "base/file_path.h"
+#include "base/file_util.h"
+#include "base/hash_tables.h"
+#include "base/lazy_instance.h"
+#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/message_loop.h"
+#include "base/message_loop_proxy.h"
+#include "base/synchronization/lock.h"
+#include "base/task.h"
+#include "base/threading/thread.h"
+
+namespace base {
+namespace files {
+
+namespace {
+
+class FilePathWatcherImpl;
+
+// Singleton to manage all inotify watches.
+// TODO(tony): It would be nice if this wasn't a singleton.
+// http://crbug.com/38174
+class InotifyReader {
+ public:
+ typedef int Watch; // Watch descriptor used by AddWatch and RemoveWatch.
+ static const Watch kInvalidWatch = -1;
+
+ // Watch directory |path| for changes. |watcher| will be notified on each
+ // change. Returns kInvalidWatch on failure.
+ Watch AddWatch(const FilePath& path, FilePathWatcherImpl* watcher);
+
+ // Remove |watch|. Returns true on success.
+ bool RemoveWatch(Watch watch, FilePathWatcherImpl* watcher);
+
+ // Callback for InotifyReaderTask.
+ void OnInotifyEvent(const inotify_event* event);
+
+ private:
+ friend struct ::base::DefaultLazyInstanceTraits<InotifyReader>;
+
+ typedef std::set<FilePathWatcherImpl*> WatcherSet;
+
+ InotifyReader();
+ ~InotifyReader();
+
+ // We keep track of which delegates want to be notified on which watches.
+ base::hash_map<Watch, WatcherSet> watchers_;
+
+ // Lock to protect watchers_.
+ base::Lock lock_;
+
+ // Separate thread on which we run blocking read for inotify events.
+ base::Thread thread_;
+
+ // File descriptor returned by inotify_init.
+ const int inotify_fd_;
+
+ // Use self-pipe trick to unblock select during shutdown.
+ int shutdown_pipe_[2];
+
+ // Flag set to true when startup was successful.
+ bool valid_;
+
+ DISALLOW_COPY_AND_ASSIGN(InotifyReader);
+};
+
+class FilePathWatcherImpl : public FilePathWatcher::PlatformDelegate,
+ public MessageLoop::DestructionObserver {
+ public:
+ FilePathWatcherImpl();
+
+ // Called for each event coming from the watch. |fired_watch| identifies the
+ // watch that fired, |child| indicates what has changed, and is relative to
+ // the currently watched path for |fired_watch|. The flag |created| is true if
+ // the object appears, and |is_directory| is set when the event refers to a
+ // directory.
+ void OnFilePathChanged(InotifyReader::Watch fired_watch,
+ const FilePath::StringType& child,
+ bool created,
+ bool is_directory);
+
+ // Start watching |path| for changes and notify |delegate| on each change.
+ // Returns true if watch for |path| has been added successfully.
+ virtual bool Watch(const FilePath& path,
+ FilePathWatcher::Delegate* delegate) OVERRIDE;
+
+ // Cancel the watch. This unregisters the instance with InotifyReader.
+ virtual void Cancel() OVERRIDE;
+
+ // Deletion of the FilePathWatcher will call Cancel() to dispose of this
+ // object in the right thread. This also observes destruction of the required
+ // cleanup thread, in case it quits before Cancel() is called.
+ virtual void WillDestroyCurrentMessageLoop() OVERRIDE;
+
+ private:
+ virtual ~FilePathWatcherImpl() {}
+
+ // Cleans up and stops observing the |message_loop_| thread.
+ void CancelOnMessageLoopThread() OVERRIDE;
+
+ // Inotify watches are installed for all directory components of |target_|. A
+ // WatchEntry instance holds the watch descriptor for a component and the
+ // subdirectory for that identifies the next component.
+ struct WatchEntry {
+ WatchEntry(InotifyReader::Watch watch, const FilePath::StringType& subdir)
+ : watch_(watch),
+ subdir_(subdir) {}
+
+ InotifyReader::Watch watch_;
+ FilePath::StringType subdir_;
+ };
+ typedef std::vector<WatchEntry> WatchVector;
+
+ // Reconfigure to watch for the most specific parent directory of |target_|
+ // that exists. Updates |watched_path_|. Returns true on success.
+ bool UpdateWatches() WARN_UNUSED_RESULT;
+
+ // Delegate to notify upon changes.
+ scoped_refptr<FilePathWatcher::Delegate> delegate_;
+
+ // The file or directory we're supposed to watch.
+ FilePath target_;
+
+ // The vector of watches and next component names for all path components,
+ // starting at the root directory. The last entry corresponds to the watch for
+ // |target_| and always stores an empty next component name in |subdir_|.
+ WatchVector watches_;
+
+ DISALLOW_COPY_AND_ASSIGN(FilePathWatcherImpl);
+};
+
+class InotifyReaderTask : public Task {
+ public:
+ InotifyReaderTask(InotifyReader* reader, int inotify_fd, int shutdown_fd)
+ : reader_(reader),
+ inotify_fd_(inotify_fd),
+ shutdown_fd_(shutdown_fd) {
+ }
+
+ virtual void Run() {
+ while (true) {
+ fd_set rfds;
+ FD_ZERO(&rfds);
+ FD_SET(inotify_fd_, &rfds);
+ FD_SET(shutdown_fd_, &rfds);
+
+ // Wait until some inotify events are available.
+ int select_result =
+ HANDLE_EINTR(select(std::max(inotify_fd_, shutdown_fd_) + 1,
+ &rfds, NULL, NULL, NULL));
+ if (select_result < 0) {
+ DPLOG(WARNING) << "select failed";
+ return;
+ }
+
+ if (FD_ISSET(shutdown_fd_, &rfds))
+ return;
+
+ // Adjust buffer size to current event queue size.
+ int buffer_size;
+ int ioctl_result = HANDLE_EINTR(ioctl(inotify_fd_, FIONREAD,
+ &buffer_size));
+
+ if (ioctl_result != 0) {
+ DPLOG(WARNING) << "ioctl failed";
+ return;
+ }
+
+ std::vector<char> buffer(buffer_size);
+
+ ssize_t bytes_read = HANDLE_EINTR(read(inotify_fd_, &buffer[0],
+ buffer_size));
+
+ if (bytes_read < 0) {
+ DPLOG(WARNING) << "read from inotify fd failed";
+ return;
+ }
+
+ ssize_t i = 0;
+ while (i < bytes_read) {
+ inotify_event* event = reinterpret_cast<inotify_event*>(&buffer[i]);
+ size_t event_size = sizeof(inotify_event) + event->len;
+ DCHECK(i + event_size <= static_cast<size_t>(bytes_read));
+ reader_->OnInotifyEvent(event);
+ i += event_size;
+ }
+ }
+ }
+
+ private:
+ InotifyReader* reader_;
+ int inotify_fd_;
+ int shutdown_fd_;
+
+ DISALLOW_COPY_AND_ASSIGN(InotifyReaderTask);
+};
+
+static base::LazyInstance<InotifyReader> g_inotify_reader(
+ base::LINKER_INITIALIZED);
+
+InotifyReader::InotifyReader()
+ : thread_("inotify_reader"),
+ inotify_fd_(inotify_init()),
+ valid_(false) {
+ shutdown_pipe_[0] = -1;
+ shutdown_pipe_[1] = -1;
+ if (inotify_fd_ >= 0 && pipe(shutdown_pipe_) == 0 && thread_.Start()) {
+ thread_.message_loop()->PostTask(
+ FROM_HERE, new InotifyReaderTask(this, inotify_fd_, shutdown_pipe_[0]));
+ valid_ = true;
+ }
+}
+
+InotifyReader::~InotifyReader() {
+ if (valid_) {
+ // Write to the self-pipe so that the select call in InotifyReaderTask
+ // returns.
+ ssize_t ret = HANDLE_EINTR(write(shutdown_pipe_[1], "", 1));
+ DPCHECK(ret > 0);
+ DCHECK_EQ(ret, 1);
+ thread_.Stop();
+ }
+ if (inotify_fd_ >= 0)
+ close(inotify_fd_);
+ if (shutdown_pipe_[0] >= 0)
+ close(shutdown_pipe_[0]);
+ if (shutdown_pipe_[1] >= 0)
+ close(shutdown_pipe_[1]);
+}
+
+InotifyReader::Watch InotifyReader::AddWatch(
+ const FilePath& path, FilePathWatcherImpl* watcher) {
+ if (!valid_)
+ return kInvalidWatch;
+
+ base::AutoLock auto_lock(lock_);
+
+ Watch watch = inotify_add_watch(inotify_fd_, path.value().c_str(),
+ IN_CREATE | IN_DELETE |
+ IN_CLOSE_WRITE | IN_MOVE |
+ IN_ONLYDIR);
+
+ if (watch == kInvalidWatch)
+ return kInvalidWatch;
+
+ watchers_[watch].insert(watcher);
+
+ return watch;
+}
+
+bool InotifyReader::RemoveWatch(Watch watch,
+ FilePathWatcherImpl* watcher) {
+ if (!valid_)
+ return false;
+
+ base::AutoLock auto_lock(lock_);
+
+ watchers_[watch].erase(watcher);
+
+ if (watchers_[watch].empty()) {
+ watchers_.erase(watch);
+ return (inotify_rm_watch(inotify_fd_, watch) == 0);
+ }
+
+ return true;
+}
+
+void InotifyReader::OnInotifyEvent(const inotify_event* event) {
+ if (event->mask & IN_IGNORED)
+ return;
+
+ FilePath::StringType child(event->len ? event->name : FILE_PATH_LITERAL(""));
+ base::AutoLock auto_lock(lock_);
+
+ for (WatcherSet::iterator watcher = watchers_[event->wd].begin();
+ watcher != watchers_[event->wd].end();
+ ++watcher) {
+ (*watcher)->OnFilePathChanged(event->wd,
+ child,
+ event->mask & (IN_CREATE | IN_MOVED_TO),
+ event->mask & IN_ISDIR);
+ }
+}
+
+FilePathWatcherImpl::FilePathWatcherImpl()
+ : delegate_(NULL) {
+}
+
+void FilePathWatcherImpl::OnFilePathChanged(
+ InotifyReader::Watch fired_watch,
+ const FilePath::StringType& child,
+ bool created,
+ bool is_directory) {
+
+ if (!message_loop()->BelongsToCurrentThread()) {
+ // Switch to message_loop_ to access watches_ safely.
+ message_loop()->PostTask(FROM_HERE,
+ NewRunnableMethod(this,
+ &FilePathWatcherImpl::OnFilePathChanged,
+ fired_watch,
+ child,
+ created,
+ is_directory));
+ return;
+ }
+
+ DCHECK(MessageLoopForIO::current());
+
+ // Find the entry in |watches_| that corresponds to |fired_watch|.
+ WatchVector::const_iterator watch_entry(watches_.begin());
+ for ( ; watch_entry != watches_.end(); ++watch_entry) {
+ if (fired_watch == watch_entry->watch_)
+ break;
+ }
+
+ // If this notification is from a previous generation of watches or the watch
+ // has been cancelled (|watches_| is empty then), bail out.
+ if (watch_entry == watches_.end())
+ return;
+
+ // Check whether a path component of |target_| changed.
+ bool change_on_target_path = child.empty() || child == watch_entry->subdir_;
+
+ // Check whether the change references |target_| or a direct child.
+ DCHECK(watch_entry->subdir_.empty() || (watch_entry + 1) != watches_.end());
+ bool target_changed = watch_entry->subdir_.empty() ||
+ (watch_entry->subdir_ == child && (++watch_entry)->subdir_.empty());
+
+ // Update watches if a directory component of the |target_| path (dis)appears.
+ if (is_directory && change_on_target_path && !UpdateWatches()) {
+ delegate_->OnFilePathError(target_);
+ return;
+ }
+
+ // Report the following events:
+ // - The target or a direct child of the target got changed (in case the
+ // watched path refers to a directory).
+ // - One of the parent directories got moved or deleted, since the target
+ // disappears in this case.
+ // - One of the parent directories appears. The event corresponding to the
+ // target appearing might have been missed in this case, so recheck.
+ if (target_changed ||
+ (change_on_target_path && !created) ||
+ (change_on_target_path && file_util::PathExists(target_))) {
+ delegate_->OnFilePathChanged(target_);
+ }
+}
+
+bool FilePathWatcherImpl::Watch(const FilePath& path,
+ FilePathWatcher::Delegate* delegate) {
+ DCHECK(target_.empty());
+ DCHECK(MessageLoopForIO::current());
+
+ set_message_loop(base::MessageLoopProxy::CreateForCurrentThread());
+ delegate_ = delegate;
+ target_ = path;
+ MessageLoop::current()->AddDestructionObserver(this);
+
+ std::vector<FilePath::StringType> comps;
+ target_.GetComponents(&comps);
+ DCHECK(!comps.empty());
+ for (std::vector<FilePath::StringType>::const_iterator comp(++comps.begin());
+ comp != comps.end(); ++comp) {
+ watches_.push_back(WatchEntry(InotifyReader::kInvalidWatch, *comp));
+ }
+ watches_.push_back(WatchEntry(InotifyReader::kInvalidWatch,
+ FilePath::StringType()));
+ return UpdateWatches();
+}
+
+void FilePathWatcherImpl::Cancel() {
+ if (!delegate_) {
+ // Watch was never called, or the |message_loop_| thread is already gone.
+ set_cancelled();
+ return;
+ }
+
+ // Switch to the message_loop_ if necessary so we can access |watches_|.
+ if (!message_loop()->BelongsToCurrentThread()) {
+ message_loop()->PostTask(FROM_HERE,
+ new FilePathWatcher::CancelTask(this));
+ } else {
+ CancelOnMessageLoopThread();
+ }
+}
+
+void FilePathWatcherImpl::CancelOnMessageLoopThread() {
+ if (!is_cancelled()) {
+ set_cancelled();
+ MessageLoop::current()->RemoveDestructionObserver(this);
+
+ for (WatchVector::iterator watch_entry(watches_.begin());
+ watch_entry != watches_.end(); ++watch_entry) {
+ if (watch_entry->watch_ != InotifyReader::kInvalidWatch)
+ g_inotify_reader.Get().RemoveWatch(watch_entry->watch_, this);
+ }
+ watches_.clear();
+ delegate_ = NULL;
+ target_.clear();
+ }
+}
+
+void FilePathWatcherImpl::WillDestroyCurrentMessageLoop() {
+ CancelOnMessageLoopThread();
+}
+
+bool FilePathWatcherImpl::UpdateWatches() {
+ // Ensure this runs on the message_loop_ exclusively in order to avoid
+ // concurrency issues.
+ DCHECK(message_loop()->BelongsToCurrentThread());
+
+ // Walk the list of watches and update them as we go.
+ FilePath path(FILE_PATH_LITERAL("/"));
+ bool path_valid = true;
+ for (WatchVector::iterator watch_entry(watches_.begin());
+ watch_entry != watches_.end(); ++watch_entry) {
+ InotifyReader::Watch old_watch = watch_entry->watch_;
+ if (path_valid) {
+ watch_entry->watch_ = g_inotify_reader.Get().AddWatch(path, this);
+ if (watch_entry->watch_ == InotifyReader::kInvalidWatch) {
+ path_valid = false;
+ }
+ } else {
+ watch_entry->watch_ = InotifyReader::kInvalidWatch;
+ }
+ if (old_watch != InotifyReader::kInvalidWatch &&
+ old_watch != watch_entry->watch_) {
+ g_inotify_reader.Get().RemoveWatch(old_watch, this);
+ }
+ path = path.Append(watch_entry->subdir_);
+ }
+
+ return true;
+}
+
+} // namespace
+
+FilePathWatcher::FilePathWatcher() {
+ impl_ = new FilePathWatcherImpl();
+}
+
+} // namespace files
+} // namespace base
diff --git a/base/files/file_path_watcher_mac.cc b/base/files/file_path_watcher_mac.cc
new file mode 100644
index 0000000..7b61f76
--- /dev/null
+++ b/base/files/file_path_watcher_mac.cc
@@ -0,0 +1,493 @@
+// Copyright (c) 2011 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.
+
+#include "base/files/file_path_watcher.h"
+
+#include <fcntl.h>
+#include <sys/event.h>
+#include <sys/param.h>
+
+#include <vector>
+
+#include "base/file_util.h"
+#include "base/message_loop.h"
+#include "base/message_loop_proxy.h"
+#include "base/stringprintf.h"
+
+namespace base {
+namespace files {
+
+namespace {
+
+// Mac-specific file watcher implementation based on kqueue.
+// Originally it was based on FSEvents so that the semantics were equivalent
+// on Linux, OSX and Windows where it was able to detect:
+// - file creation/deletion/modification in a watched directory
+// - file creation/deletion/modification for a watched file
+// - modifications to the paths to a watched object that would affect the
+// object such as renaming/attibute changes etc.
+// The FSEvents version did all of the above except handling attribute changes
+// to path components. Unfortunately FSEvents appears to have an issue where the
+// current implementation (Mac OS X 10.6.7) sometimes drops events and doesn't
+// send notifications. See
+// http://code.google.com/p/chromium/issues/detail?id=54822#c31 for source that
+// will reproduce the problem. FSEvents also required having a CFRunLoop
+// backing the thread that it was running on, that caused added complexity
+// in the interfaces.
+// The kqueue implementation will handle all of the items in the list above
+// except for detecting modifications to files in a watched directory. It will
+// detect the creation and deletion of files, just not the modification of
+// files. It does however detect the attribute changes that the FSEvents impl
+// would miss.
+class FilePathWatcherImpl : public FilePathWatcher::PlatformDelegate,
+ public MessageLoopForIO::Watcher,
+ public MessageLoop::DestructionObserver {
+ public:
+ FilePathWatcherImpl() : kqueue_(-1) {}
+ virtual ~FilePathWatcherImpl() {}
+
+ // MessageLoopForIO::Watcher overrides.
+ virtual void OnFileCanReadWithoutBlocking(int fd) OVERRIDE;
+ virtual void OnFileCanWriteWithoutBlocking(int fd) OVERRIDE;
+
+ // MessageLoop::DestructionObserver overrides.
+ virtual void WillDestroyCurrentMessageLoop() OVERRIDE;
+
+ // FilePathWatcher::PlatformDelegate overrides.
+ virtual bool Watch(const FilePath& path,
+ FilePathWatcher::Delegate* delegate) OVERRIDE;
+ virtual void Cancel() OVERRIDE;
+
+ private:
+ class EventData {
+ public:
+ EventData(const FilePath& path, const FilePath::StringType& subdir)
+ : path_(path), subdir_(subdir) { }
+ FilePath path_; // Full path to this item.
+ FilePath::StringType subdir_; // Path to any sub item.
+ };
+ typedef std::vector<struct kevent> EventVector;
+
+ // Can only be called on |io_message_loop_|'s thread.
+ virtual void CancelOnMessageLoopThread() OVERRIDE;
+
+ // Returns true if the kevent values are error free.
+ bool AreKeventValuesValid(struct kevent* kevents, int count);
+
+ // Respond to a change of attributes of the path component represented by
+ // |event|. Sets |target_file_affected| to true if |target_| is affected.
+ // Sets |update_watches| to true if |events_| need to be updated.
+ void HandleAttributesChange(const EventVector::iterator& event,
+ bool* target_file_affected,
+ bool* update_watches);
+
+ // Respond to a move of deletion of the path component represented by
+ // |event|. Sets |target_file_affected| to true if |target_| is affected.
+ // Sets |update_watches| to true if |events_| need to be updated.
+ void HandleDeleteOrMoveChange(const EventVector::iterator& event,
+ bool* target_file_affected,
+ bool* update_watches);
+
+ // Respond to a creation of an item in the path component represented by
+ // |event|. Sets |target_file_affected| to true if |target_| is affected.
+ // Sets |update_watches| to true if |events_| need to be updated.
+ void HandleCreateItemChange(const EventVector::iterator& event,
+ bool* target_file_affected,
+ bool* update_watches);
+
+ // Update |events_| with the current status of the system.
+ // Sets |target_file_affected| to true if |target_| is affected.
+ // Returns false if an error occurs.
+ bool UpdateWatches(bool* target_file_affected);
+
+ // Fills |events| with one kevent per component in |path|.
+ // Returns the number of valid events created where a valid event is
+ // defined as one that has a ident (file descriptor) field != -1.
+ static int EventsForPath(FilePath path, EventVector *events);
+
+ // Release a kevent generated by EventsForPath.
+ static void ReleaseEvent(struct kevent& event);
+
+ // Returns a file descriptor that will not block the system from deleting
+ // the file it references.
+ static int FileDescriptorForPath(const FilePath& path);
+
+ // Closes |*fd| and sets |*fd| to -1.
+ static void CloseFileDescriptor(int* fd);
+
+ // Returns true if kevent has open file descriptor.
+ static bool IsKeventFileDescriptorOpen(const struct kevent& event) {
+ return event.ident != static_cast<uintptr_t>(-1);
+ }
+
+ static EventData* EventDataForKevent(const struct kevent& event) {
+ return reinterpret_cast<EventData*>(event.udata);
+ }
+
+ EventVector events_;
+ scoped_refptr<base::MessageLoopProxy> io_message_loop_;
+ MessageLoopForIO::FileDescriptorWatcher kqueue_watcher_;
+ scoped_refptr<FilePathWatcher::Delegate> delegate_;
+ FilePath target_;
+ int kqueue_;
+
+ DISALLOW_COPY_AND_ASSIGN(FilePathWatcherImpl);
+};
+
+void FilePathWatcherImpl::ReleaseEvent(struct kevent& event) {
+ CloseFileDescriptor(reinterpret_cast<int*>(&event.ident));
+ EventData* entry = EventDataForKevent(event);
+ delete entry;
+ event.udata = NULL;
+}
+
+int FilePathWatcherImpl::EventsForPath(FilePath path, EventVector* events) {
+ DCHECK(MessageLoopForIO::current());
+ // Make sure that we are working with a clean slate.
+ DCHECK(events->empty());
+
+ std::vector<FilePath::StringType> components;
+ path.GetComponents(&components);
+
+ if (components.size() < 1) {
+ return -1;
+ }
+
+ int last_existing_entry = 0;
+ FilePath built_path;
+ bool path_still_exists = true;
+ for(std::vector<FilePath::StringType>::iterator i = components.begin();
+ i != components.end(); ++i) {
+ if (i == components.begin()) {
+ built_path = FilePath(*i);
+ } else {
+ built_path = built_path.Append(*i);
+ }
+ int fd = -1;
+ if (path_still_exists) {
+ fd = FileDescriptorForPath(built_path);
+ if (fd == -1) {
+ path_still_exists = false;
+ } else {
+ ++last_existing_entry;
+ }
+ }
+ FilePath::StringType subdir = (i != (components.end() - 1)) ? *(i + 1) : "";
+ EventData* data = new EventData(built_path, subdir);
+ struct kevent event;
+ EV_SET(&event, fd, EVFILT_VNODE, (EV_ADD | EV_CLEAR | EV_RECEIPT),
+ (NOTE_DELETE | NOTE_WRITE | NOTE_ATTRIB |
+ NOTE_RENAME | NOTE_REVOKE | NOTE_EXTEND), 0, data);
+ events->push_back(event);
+ }
+ return last_existing_entry;
+}
+
+int FilePathWatcherImpl::FileDescriptorForPath(const FilePath& path) {
+ return HANDLE_EINTR(open(path.value().c_str(), O_EVTONLY));
+}
+
+void FilePathWatcherImpl::CloseFileDescriptor(int *fd) {
+ if (*fd == -1) {
+ return;
+ }
+
+ if (HANDLE_EINTR(close(*fd)) != 0) {
+ PLOG(ERROR) << "close";
+ }
+ *fd = -1;
+}
+
+bool FilePathWatcherImpl::AreKeventValuesValid(struct kevent* kevents,
+ int count) {
+ if (count < 0) {
+ PLOG(ERROR) << "kevent";
+ return false;
+ }
+ bool valid = true;
+ for (int i = 0; i < count; ++i) {
+ if (kevents[i].flags & EV_ERROR && kevents[i].data) {
+ // Find the kevent in |events_| that matches the kevent with the error.
+ EventVector::iterator event = events_.begin();
+ for (; event != events_.end(); ++event) {
+ if (event->ident == kevents[i].ident) {
+ break;
+ }
+ }
+ std::string path_name;
+ if (event != events_.end()) {
+ EventData* event_data = EventDataForKevent(*event);
+ if (event_data != NULL) {
+ path_name = event_data->path_.value();
+ }
+ }
+ if (path_name.empty()) {
+ path_name = base::StringPrintf(
+ "fd %d", *reinterpret_cast<int*>(&kevents[i].ident));
+ }
+ LOG(ERROR) << "Error: " << kevents[i].data << " for " << path_name;
+ valid = false;
+ }
+ }
+ return valid;
+}
+
+void FilePathWatcherImpl::HandleAttributesChange(
+ const EventVector::iterator& event,
+ bool* target_file_affected,
+ bool* update_watches) {
+ EventVector::iterator next_event = event + 1;
+ EventData* next_event_data = EventDataForKevent(*next_event);
+ // Check to see if the next item in path is still accessible.
+ int have_access = FileDescriptorForPath(next_event_data->path_);
+ if (have_access == -1) {
+ *target_file_affected = true;
+ *update_watches = true;
+ EventVector::iterator local_event(event);
+ for (; local_event != events_.end(); ++local_event) {
+ // Close all nodes from the event down. This has the side effect of
+ // potentially rendering other events in |updates| invalid.
+ // There is no need to remove the events from |kqueue_| because this
+ // happens as a side effect of closing the file descriptor.
+ CloseFileDescriptor(reinterpret_cast<int*>(&local_event->ident));
+ }
+ } else {
+ CloseFileDescriptor(&have_access);
+ }
+}
+
+void FilePathWatcherImpl::HandleDeleteOrMoveChange(
+ const EventVector::iterator& event,
+ bool* target_file_affected,
+ bool* update_watches) {
+ *target_file_affected = true;
+ *update_watches = true;
+ EventVector::iterator local_event(event);
+ for (; local_event != events_.end(); ++local_event) {
+ // Close all nodes from the event down. This has the side effect of
+ // potentially rendering other events in |updates| invalid.
+ // There is no need to remove the events from |kqueue_| because this
+ // happens as a side effect of closing the file descriptor.
+ CloseFileDescriptor(reinterpret_cast<int*>(&local_event->ident));
+ }
+}
+
+void FilePathWatcherImpl::HandleCreateItemChange(
+ const EventVector::iterator& event,
+ bool* target_file_affected,
+ bool* update_watches) {
+ // Get the next item in the path.
+ EventVector::iterator next_event = event + 1;
+ EventData* next_event_data = EventDataForKevent(*next_event);
+
+ // Check to see if it already has a valid file descriptor.
+ if (!IsKeventFileDescriptorOpen(*next_event)) {
+ // If not, attempt to open a file descriptor for it.
+ next_event->ident = FileDescriptorForPath(next_event_data->path_);
+ if (IsKeventFileDescriptorOpen(*next_event)) {
+ *update_watches = true;
+ if (next_event_data->subdir_.empty()) {
+ *target_file_affected = true;
+ }
+ }
+ }
+}
+
+bool FilePathWatcherImpl::UpdateWatches(bool* target_file_affected) {
+ // Iterate over events adding kevents for items that exist to the kqueue.
+ // Then check to see if new components in the path have been created.
+ // Repeat until no new components in the path are detected.
+ // This is to get around races in directory creation in a watched path.
+ bool update_watches = true;
+ while (update_watches) {
+ size_t valid;
+ for (valid = 0; valid < events_.size(); ++valid) {
+ if (!IsKeventFileDescriptorOpen(events_[valid])) {
+ break;
+ }
+ }
+ if (valid == 0) {
+ // The root of the file path is inaccessible?
+ return false;
+ }
+
+ EventVector updates(valid);
+ int count = HANDLE_EINTR(kevent(kqueue_, &events_[0], valid, &updates[0],
+ valid, NULL));
+ if (!AreKeventValuesValid(&updates[0], count)) {
+ return false;
+ }
+ update_watches = false;
+ for (; valid < events_.size(); ++valid) {
+ EventData* event_data = EventDataForKevent(events_[valid]);
+ events_[valid].ident = FileDescriptorForPath(event_data->path_);
+ if (IsKeventFileDescriptorOpen(events_[valid])) {
+ update_watches = true;
+ if (event_data->subdir_.empty()) {
+ *target_file_affected = true;
+ }
+ } else {
+ break;
+ }
+ }
+ }
+ return true;
+}
+
+void FilePathWatcherImpl::OnFileCanReadWithoutBlocking(int fd) {
+ DCHECK(MessageLoopForIO::current());
+ CHECK_EQ(fd, kqueue_);
+ CHECK(events_.size());
+
+ // Request the file system update notifications that have occurred and return
+ // them in |updates|. |count| will contain the number of updates that have
+ // occurred.
+ EventVector updates(events_.size());
+ struct timespec timeout = {0, 0};
+ int count = HANDLE_EINTR(kevent(kqueue_, NULL, 0, &updates[0], updates.size(),
+ &timeout));
+
+ // Error values are stored within updates, so check to make sure that no
+ // errors occurred.
+ if (!AreKeventValuesValid(&updates[0], count)) {
+ delegate_->OnFilePathError(target_);
+ Cancel();
+ return;
+ }
+
+ bool update_watches = false;
+ bool send_notification = false;
+
+ // Iterate through each of the updates and react to them.
+ for (int i = 0; i < count; ++i) {
+ // Find our kevent record that matches the update notification.
+ EventVector::iterator event = events_.begin();
+ for (; event != events_.end(); ++event) {
+ if (!IsKeventFileDescriptorOpen(*event) ||
+ event->ident == updates[i].ident) {
+ break;
+ }
+ }
+ if (!IsKeventFileDescriptorOpen(*event) || event == events_.end()) {
+ // The event may no longer exist in |events_| because another event
+ // modified |events_| in such a way to make it invalid. For example if
+ // the path is /foo/bar/bam and foo is deleted, NOTE_DELETE events for
+ // foo, bar and bam will be sent. If foo is processed first, then
+ // the file descriptors for bar and bam will already be closed and set
+ // to -1 before they get a chance to be processed.
+ continue;
+ }
+
+ EventData* event_data = EventDataForKevent(*event);
+
+ // If the subdir is empty, this is the last item on the path and is the
+ // target file.
+ bool target_file_affected = event_data->subdir_.empty();
+ if ((updates[i].fflags & NOTE_ATTRIB) && !target_file_affected) {
+ HandleAttributesChange(event, &target_file_affected, &update_watches);
+ }
+ if (updates[i].fflags & (NOTE_DELETE | NOTE_REVOKE | NOTE_RENAME)) {
+ HandleDeleteOrMoveChange(event, &target_file_affected, &update_watches);
+ }
+ if ((updates[i].fflags & NOTE_WRITE) && !target_file_affected) {
+ HandleCreateItemChange(event, &target_file_affected, &update_watches);
+ }
+ send_notification |= target_file_affected;
+ }
+
+ if (update_watches) {
+ if (!UpdateWatches(&send_notification)) {
+ delegate_->OnFilePathError(target_);
+ Cancel();
+ }
+ }
+
+ if (send_notification) {
+ delegate_->OnFilePathChanged(target_);
+ }
+}
+
+void FilePathWatcherImpl::OnFileCanWriteWithoutBlocking(int fd) {
+ NOTREACHED();
+}
+
+void FilePathWatcherImpl::WillDestroyCurrentMessageLoop() {
+ CancelOnMessageLoopThread();
+}
+
+bool FilePathWatcherImpl::Watch(const FilePath& path,
+ FilePathWatcher::Delegate* delegate) {
+ DCHECK(MessageLoopForIO::current());
+ DCHECK(target_.value().empty()); // Can only watch one path.
+ DCHECK(delegate);
+ DCHECK_EQ(kqueue_, -1);
+
+ delegate_ = delegate;
+ target_ = path;
+
+ MessageLoop::current()->AddDestructionObserver(this);
+ io_message_loop_ = base::MessageLoopProxy::CreateForCurrentThread();
+
+ kqueue_ = kqueue();
+ if (kqueue_ == -1) {
+ PLOG(ERROR) << "kqueue";
+ return false;
+ }
+
+ int last_entry = EventsForPath(target_, &events_);
+ CHECK_NE(last_entry, 0);
+
+ EventVector responses(last_entry);
+
+ int count = HANDLE_EINTR(kevent(kqueue_, &events_[0], last_entry,
+ &responses[0], last_entry, NULL));
+ if (!AreKeventValuesValid(&responses[0], count)) {
+ // Calling Cancel() here to close any file descriptors that were opened.
+ // This would happen in the destructor anyways, but FilePathWatchers tend to
+ // be long lived, and if an error has occurred, there is no reason to waste
+ // the file descriptors.
+ Cancel();
+ return false;
+ }
+
+ return MessageLoopForIO::current()->WatchFileDescriptor(
+ kqueue_, true, MessageLoopForIO::WATCH_READ, &kqueue_watcher_, this);
+}
+
+void FilePathWatcherImpl::Cancel() {
+ base::MessageLoopProxy* proxy = io_message_loop_.get();
+ if (!proxy) {
+ set_cancelled();
+ return;
+ }
+ if (!proxy->BelongsToCurrentThread()) {
+ proxy->PostTask(FROM_HERE,
+ NewRunnableMethod(this, &FilePathWatcherImpl::Cancel));
+ return;
+ }
+ CancelOnMessageLoopThread();
+}
+
+void FilePathWatcherImpl::CancelOnMessageLoopThread() {
+ DCHECK(MessageLoopForIO::current());
+ if (!is_cancelled()) {
+ set_cancelled();
+ kqueue_watcher_.StopWatchingFileDescriptor();
+ CloseFileDescriptor(&kqueue_);
+ std::for_each(events_.begin(), events_.end(), ReleaseEvent);
+ events_.clear();
+ io_message_loop_ = NULL;
+ MessageLoop::current()->RemoveDestructionObserver(this);
+ delegate_ = NULL;
+ }
+}
+
+} // namespace
+
+FilePathWatcher::FilePathWatcher() {
+ impl_ = new FilePathWatcherImpl();
+}
+
+} // namespace files
+} // namespace base
diff --git a/base/files/file_path_watcher_stub.cc b/base/files/file_path_watcher_stub.cc
new file mode 100644
index 0000000..a693dc7
--- /dev/null
+++ b/base/files/file_path_watcher_stub.cc
@@ -0,0 +1,31 @@
+// Copyright (c) 2011 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.
+
+// This file exists for Unix systems which don't have the inotify headers, and
+// thus cannot build file_watcher_inotify.cc
+
+#include "base/files/file_path_watcher.h"
+
+namespace base {
+namespace files {
+
+namespace {
+
+class FilePathWatcherImpl : public FilePathWatcher::PlatformDelegate {
+ public:
+ virtual bool Watch(const FilePath& path,
+ FileWatcher::Delegate* delegate,
+ base::MessageLoopProxy*) OVERRIDE {
+ return false;
+ }
+};
+
+} // namespace
+
+FilePathWatcher::FilePathWatcher() {
+ impl_ = new FilePathWatcherImpl();
+}
+
+} // namespace files
+} // namespace base
diff --git a/base/files/file_path_watcher_win.cc b/base/files/file_path_watcher_win.cc
new file mode 100644
index 0000000..eedcf22
--- /dev/null
+++ b/base/files/file_path_watcher_win.cc
@@ -0,0 +1,281 @@
+// Copyright (c) 2011 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.
+
+#include "base/files/file_path_watcher.h"
+
+#include "base/file_path.h"
+#include "base/file_util.h"
+#include "base/logging.h"
+#include "base/memory/ref_counted.h"
+#include "base/message_loop_proxy.h"
+#include "base/time.h"
+#include "base/win/object_watcher.h"
+
+namespace base {
+namespace files {
+
+namespace {
+
+class FilePathWatcherImpl : public FilePathWatcher::PlatformDelegate,
+ public base::win::ObjectWatcher::Delegate,
+ public MessageLoop::DestructionObserver {
+ public:
+ FilePathWatcherImpl() : delegate_(NULL), handle_(INVALID_HANDLE_VALUE) {}
+
+ // FilePathWatcher::PlatformDelegate overrides.
+ virtual bool Watch(const FilePath& path,
+ FilePathWatcher::Delegate* delegate) OVERRIDE;
+ virtual void Cancel() OVERRIDE;
+
+ // Deletion of the FilePathWatcher will call Cancel() to dispose of this
+ // object in the right thread. This also observes destruction of the required
+ // cleanup thread, in case it quits before Cancel() is called.
+ virtual void WillDestroyCurrentMessageLoop() OVERRIDE;
+
+ // Callback from MessageLoopForIO.
+ virtual void OnObjectSignaled(HANDLE object);
+
+ private:
+ virtual ~FilePathWatcherImpl() {}
+
+ // Setup a watch handle for directory |dir|. Returns true if no fatal error
+ // occurs. |handle| will receive the handle value if |dir| is watchable,
+ // otherwise INVALID_HANDLE_VALUE.
+ static bool SetupWatchHandle(const FilePath& dir, HANDLE* handle)
+ WARN_UNUSED_RESULT;
+
+ // (Re-)Initialize the watch handle.
+ bool UpdateWatch() WARN_UNUSED_RESULT;
+
+ // Destroy the watch handle.
+ void DestroyWatch();
+
+ // Cleans up and stops observing the |message_loop_| thread.
+ void CancelOnMessageLoopThread() OVERRIDE;
+
+ // Delegate to notify upon changes.
+ scoped_refptr<FilePathWatcher::Delegate> delegate_;
+
+ // Path we're supposed to watch (passed to delegate).
+ FilePath target_;
+
+ // Handle for FindFirstChangeNotification.
+ HANDLE handle_;
+
+ // ObjectWatcher to watch handle_ for events.
+ base::win::ObjectWatcher watcher_;
+
+ // Keep track of the last modified time of the file. We use nulltime
+ // to represent the file not existing.
+ base::Time last_modified_;
+
+ // The time at which we processed the first notification with the
+ // |last_modified_| time stamp.
+ base::Time first_notification_;
+
+ DISALLOW_COPY_AND_ASSIGN(FilePathWatcherImpl);
+};
+
+bool FilePathWatcherImpl::Watch(const FilePath& path,
+ FilePathWatcher::Delegate* delegate) {
+ DCHECK(target_.value().empty()); // Can only watch one path.
+
+ set_message_loop(base::MessageLoopProxy::CreateForCurrentThread());
+ delegate_ = delegate;
+ target_ = path;
+ MessageLoop::current()->AddDestructionObserver(this);
+
+ if (!UpdateWatch())
+ return false;
+
+ watcher_.StartWatching(handle_, this);
+
+ return true;
+}
+
+void FilePathWatcherImpl::Cancel() {
+ if (!delegate_) {
+ // Watch was never called, or the |message_loop_| has already quit.
+ set_cancelled();
+ return;
+ }
+
+ // Switch to the file thread if necessary so we can stop |watcher_|.
+ if (!message_loop()->BelongsToCurrentThread()) {
+ message_loop()->PostTask(FROM_HERE,
+ new FilePathWatcher::CancelTask(this));
+ } else {
+ CancelOnMessageLoopThread();
+ }
+}
+
+void FilePathWatcherImpl::CancelOnMessageLoopThread() {
+ set_cancelled();
+
+ if (handle_ != INVALID_HANDLE_VALUE)
+ DestroyWatch();
+
+ if (delegate_) {
+ MessageLoop::current()->RemoveDestructionObserver(this);
+ delegate_ = NULL;
+ }
+}
+
+void FilePathWatcherImpl::WillDestroyCurrentMessageLoop() {
+ CancelOnMessageLoopThread();
+}
+
+void FilePathWatcherImpl::OnObjectSignaled(HANDLE object) {
+ DCHECK(object == handle_);
+ // Make sure we stay alive through the body of this function.
+ scoped_refptr<FilePathWatcherImpl> keep_alive(this);
+
+ if (!UpdateWatch()) {
+ delegate_->OnFilePathError(target_);
+ return;
+ }
+
+ // Check whether the event applies to |target_| and notify the delegate.
+ base::PlatformFileInfo file_info;
+ bool file_exists = file_util::GetFileInfo(target_, &file_info);
+ if (file_exists && (last_modified_.is_null() ||
+ last_modified_ != file_info.last_modified)) {
+ last_modified_ = file_info.last_modified;
+ first_notification_ = base::Time::Now();
+ delegate_->OnFilePathChanged(target_);
+ } else if (file_exists && !first_notification_.is_null()) {
+ // The target's last modification time is equal to what's on record. This
+ // means that either an unrelated event occurred, or the target changed
+ // again (file modification times only have a resolution of 1s). Comparing
+ // file modification times against the wall clock is not reliable to find
+ // out whether the change is recent, since this code might just run too
+ // late. Moreover, there's no guarantee that file modification time and wall
+ // clock times come from the same source.
+ //
+ // Instead, the time at which the first notification carrying the current
+ // |last_notified_| time stamp is recorded. Later notifications that find
+ // the same file modification time only need to be forwarded until wall
+ // clock has advanced one second from the initial notification. After that
+ // interval, client code is guaranteed to having seen the current revision
+ // of the file.
+ if (base::Time::Now() - first_notification_ >
+ base::TimeDelta::FromSeconds(1)) {
+ // Stop further notifications for this |last_modification_| time stamp.
+ first_notification_ = base::Time();
+ }
+ delegate_->OnFilePathChanged(target_);
+ } else if (!file_exists && !last_modified_.is_null()) {
+ last_modified_ = base::Time();
+ delegate_->OnFilePathChanged(target_);
+ }
+
+ // The watch may have been cancelled by the callback.
+ if (handle_ != INVALID_HANDLE_VALUE)
+ watcher_.StartWatching(handle_, this);
+}
+
+// static
+bool FilePathWatcherImpl::SetupWatchHandle(const FilePath& dir,
+ HANDLE* handle) {
+ *handle = FindFirstChangeNotification(
+ dir.value().c_str(),
+ false, // Don't watch subtrees
+ FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_SIZE |
+ FILE_NOTIFY_CHANGE_LAST_WRITE | FILE_NOTIFY_CHANGE_DIR_NAME |
+ FILE_NOTIFY_CHANGE_ATTRIBUTES | FILE_NOTIFY_CHANGE_SECURITY);
+ if (*handle != INVALID_HANDLE_VALUE) {
+ // Make sure the handle we got points to an existing directory. It seems
+ // that windows sometimes hands out watches to direectories that are
+ // about to go away, but doesn't sent notifications if that happens.
+ if (!file_util::DirectoryExists(dir)) {
+ FindCloseChangeNotification(*handle);
+ *handle = INVALID_HANDLE_VALUE;
+ }
+ return true;
+ }
+
+ // If FindFirstChangeNotification failed because the target directory
+ // doesn't exist, access is denied (happens if the file is already gone but
+ // there are still handles open), or the target is not a directory, try the
+ // immediate parent directory instead.
+ DWORD error_code = GetLastError();
+ if (error_code != ERROR_FILE_NOT_FOUND &&
+ error_code != ERROR_PATH_NOT_FOUND &&
+ error_code != ERROR_ACCESS_DENIED &&
+ error_code != ERROR_SHARING_VIOLATION &&
+ error_code != ERROR_DIRECTORY) {
+ using ::operator<<; // Pick the right operator<< below.
+ PLOG(ERROR) << "FindFirstChangeNotification failed for "
+ << dir.value();
+ return false;
+ }
+
+ return true;
+}
+
+bool FilePathWatcherImpl::UpdateWatch() {
+ if (handle_ != INVALID_HANDLE_VALUE)
+ DestroyWatch();
+
+ base::PlatformFileInfo file_info;
+ if (file_util::GetFileInfo(target_, &file_info)) {
+ last_modified_ = file_info.last_modified;
+ first_notification_ = base::Time::Now();
+ }
+
+ // Start at the target and walk up the directory chain until we succesfully
+ // create a watch handle in |handle_|. |child_dirs| keeps a stack of child
+ // directories stripped from target, in reverse order.
+ std::vector<FilePath> child_dirs;
+ FilePath watched_path(target_);
+ while (true) {
+ if (!SetupWatchHandle(watched_path, &handle_))
+ return false;
+
+ // Break if a valid handle is returned. Try the parent directory otherwise.
+ if (handle_ != INVALID_HANDLE_VALUE)
+ break;
+
+ // Abort if we hit the root directory.
+ child_dirs.push_back(watched_path.BaseName());
+ FilePath parent(watched_path.DirName());
+ if (parent == watched_path) {
+ LOG(ERROR) << "Reached the root directory";
+ return false;
+ }
+ watched_path = parent;
+ }
+
+ // At this point, handle_ is valid. However, the bottom-up search that the
+ // above code performs races against directory creation. So try to walk back
+ // down and see whether any children appeared in the mean time.
+ while (!child_dirs.empty()) {
+ watched_path = watched_path.Append(child_dirs.back());
+ child_dirs.pop_back();
+ HANDLE temp_handle = INVALID_HANDLE_VALUE;
+ if (!SetupWatchHandle(watched_path, &temp_handle))
+ return false;
+ if (temp_handle == INVALID_HANDLE_VALUE)
+ break;
+ FindCloseChangeNotification(handle_);
+ handle_ = temp_handle;
+ }
+
+ return true;
+}
+
+void FilePathWatcherImpl::DestroyWatch() {
+ watcher_.StopWatching();
+ FindCloseChangeNotification(handle_);
+ handle_ = INVALID_HANDLE_VALUE;
+}
+
+} // namespace
+
+FilePathWatcher::FilePathWatcher() {
+ impl_ = new FilePathWatcherImpl();
+}
+
+} // namespace files
+} // namespace base
diff --git a/base/global_descriptors_posix.h b/base/global_descriptors_posix.h
index 060bf0a..d635cff 100644
--- a/base/global_descriptors_posix.h
+++ b/base/global_descriptors_posix.h
@@ -13,7 +13,7 @@
#include <stdint.h>
-#include "base/singleton.h"
+#include "base/memory/singleton.h"
namespace base {
diff --git a/base/hmac.h b/base/hmac.h
deleted file mode 100644
index d467e1a..0000000
--- a/base/hmac.h
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright (c) 2006-2008 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.
-
-// Utility class for calculating the HMAC for a given message. We currently
-// only support SHA1 for the hash algorithm, but this can be extended easily.
-
-#ifndef BASE_HMAC_H_
-#define BASE_HMAC_H_
-#pragma once
-
-#include <string>
-
-#include "base/basictypes.h"
-#include "base/scoped_ptr.h"
-
-namespace base {
-
-// Simplify the interface and reduce includes by abstracting out the internals.
-struct HMACPlatformData;
-
-class HMAC {
- public:
- // The set of supported hash functions. Extend as required.
- enum HashAlgorithm {
- SHA1,
- SHA256,
- };
-
- explicit HMAC(HashAlgorithm hash_alg);
- ~HMAC();
-
- // Initializes this instance using |key| of the length |key_length|. Call Init
- // only once. It returns false on the second or later calls.
- bool Init(const unsigned char* key, int key_length);
-
- // Initializes this instance using |key|. Call Init only once. It returns
- // false on the second or later calls.
- bool Init(const std::string& key) {
- return Init(reinterpret_cast<const unsigned char*>(key.data()),
- static_cast<int>(key.size()));
- }
-
- // Calculates the HMAC for the message in |data| using the algorithm supplied
- // to the constructor and the key supplied to the Init method. The HMAC is
- // returned in |digest|, which has |digest_length| bytes of storage available.
- bool Sign(const std::string& data, unsigned char* digest, int digest_length);
-
- // TODO(albertb): Add a Verify method.
-
- private:
- HashAlgorithm hash_alg_;
- scoped_ptr<HMACPlatformData> plat_;
-
- DISALLOW_COPY_AND_ASSIGN(HMAC);
-};
-
-} // namespace base
-
-#endif // BASE_HMAC_H_
diff --git a/base/hmac_mac.cc b/base/hmac_mac.cc
deleted file mode 100644
index 97dcbf5..0000000
--- a/base/hmac_mac.cc
+++ /dev/null
@@ -1,73 +0,0 @@
-// 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.
-
-#include "base/hmac.h"
-
-#include <CommonCrypto/CommonHMAC.h>
-
-#include "base/logging.h"
-
-namespace base {
-
-struct HMACPlatformData {
- std::string key_;
-};
-
-HMAC::HMAC(HashAlgorithm hash_alg)
- : hash_alg_(hash_alg), plat_(new HMACPlatformData()) {
- // Only SHA-1 and SHA-256 hash algorithms are supported now.
- DCHECK(hash_alg_ == SHA1 || hash_alg_ == SHA256);
-}
-
-bool HMAC::Init(const unsigned char *key, int key_length) {
- if (!plat_->key_.empty()) {
- // Init must not be called more than once on the same HMAC object.
- NOTREACHED();
- return false;
- }
-
- plat_->key_.assign(reinterpret_cast<const char*>(key), key_length);
-
- return true;
-}
-
-HMAC::~HMAC() {
- // Zero out key copy.
- plat_->key_.assign(plat_->key_.length(), std::string::value_type());
- plat_->key_.clear();
- plat_->key_.reserve(0);
-}
-
-bool HMAC::Sign(const std::string& data,
- unsigned char* digest,
- int digest_length) {
- CCHmacAlgorithm algorithm;
- int algorithm_digest_length;
- switch (hash_alg_) {
- case SHA1:
- algorithm = kCCHmacAlgSHA1;
- algorithm_digest_length = CC_SHA1_DIGEST_LENGTH;
- break;
- case SHA256:
- algorithm = kCCHmacAlgSHA256;
- algorithm_digest_length = CC_SHA256_DIGEST_LENGTH;
- break;
- default:
- NOTREACHED();
- return false;
- }
-
- if (digest_length < algorithm_digest_length) {
- NOTREACHED();
- return false;
- }
-
- CCHmac(algorithm,
- plat_->key_.data(), plat_->key_.length(), data.data(), data.length(),
- digest);
-
- return true;
-}
-
-} // namespace base
diff --git a/base/hmac_nss.cc b/base/hmac_nss.cc
deleted file mode 100644
index af0b3eb..0000000
--- a/base/hmac_nss.cc
+++ /dev/null
@@ -1,117 +0,0 @@
-// 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.
-
-#include "base/hmac.h"
-
-#include <nss.h>
-#include <pk11pub.h>
-
-#include "base/crypto/scoped_nss_types.h"
-#include "base/logging.h"
-#include "base/nss_util.h"
-#include "base/scoped_ptr.h"
-
-namespace base {
-
-struct HMACPlatformData {
- CK_MECHANISM_TYPE mechanism_;
- ScopedPK11Slot slot_;
- ScopedPK11SymKey sym_key_;
-};
-
-HMAC::HMAC(HashAlgorithm hash_alg)
- : hash_alg_(hash_alg), plat_(new HMACPlatformData()) {
- // Only SHA-1 and SHA-256 hash algorithms are supported.
- switch (hash_alg_) {
- case SHA1:
- plat_->mechanism_ = CKM_SHA_1_HMAC;
- break;
- case SHA256:
- plat_->mechanism_ = CKM_SHA256_HMAC;
- break;
- default:
- NOTREACHED() << "Unsupported hash algorithm";
- break;
- }
-}
-
-HMAC::~HMAC() {
-}
-
-bool HMAC::Init(const unsigned char *key, int key_length) {
- base::EnsureNSSInit();
-
- if (plat_->slot_.get()) {
- // Init must not be called more than twice on the same HMAC object.
- NOTREACHED();
- return false;
- }
-
- plat_->slot_.reset(PK11_GetBestSlot(plat_->mechanism_, NULL));
- if (!plat_->slot_.get()) {
- NOTREACHED();
- return false;
- }
-
- SECItem key_item;
- key_item.type = siBuffer;
- key_item.data = const_cast<unsigned char*>(key); // NSS API isn't const.
- key_item.len = key_length;
-
- plat_->sym_key_.reset(PK11_ImportSymKey(plat_->slot_.get(),
- plat_->mechanism_,
- PK11_OriginUnwrap,
- CKA_SIGN,
- &key_item,
- NULL));
- if (!plat_->sym_key_.get()) {
- NOTREACHED();
- return false;
- }
-
- return true;
-}
-
-bool HMAC::Sign(const std::string& data,
- unsigned char* digest,
- int digest_length) {
- if (!plat_->sym_key_.get()) {
- // Init has not been called before Sign.
- NOTREACHED();
- return false;
- }
-
- SECItem param = { siBuffer, NULL, 0 };
- ScopedPK11Context context(PK11_CreateContextBySymKey(plat_->mechanism_,
- CKA_SIGN,
- plat_->sym_key_.get(),
- &param));
- if (!context.get()) {
- NOTREACHED();
- return false;
- }
-
- if (PK11_DigestBegin(context.get()) != SECSuccess) {
- NOTREACHED();
- return false;
- }
-
- if (PK11_DigestOp(context.get(),
- reinterpret_cast<const unsigned char*>(data.data()),
- data.length()) != SECSuccess) {
- NOTREACHED();
- return false;
- }
-
- unsigned int len = 0;
- if (PK11_DigestFinal(context.get(),
- digest, &len, digest_length) != SECSuccess) {
- NOTREACHED();
- return false;
- }
-
- return true;
-}
-
-} // namespace base
diff --git a/base/hmac_openssl.cc b/base/hmac_openssl.cc
deleted file mode 100644
index f45d3a7..0000000
--- a/base/hmac_openssl.cc
+++ /dev/null
@@ -1,57 +0,0 @@
-// 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.
-
-#include "base/hmac.h"
-
-#include <openssl/hmac.h>
-
-#include <algorithm>
-#include <vector>
-
-#include "base/logging.h"
-#include "base/openssl_util.h"
-#include "base/scoped_ptr.h"
-#include "base/stl_util-inl.h"
-
-namespace base {
-
-struct HMACPlatformData {
- std::vector<unsigned char> key;
-};
-
-HMAC::HMAC(HashAlgorithm hash_alg)
- : hash_alg_(hash_alg), plat_(new HMACPlatformData()) {
- // Only SHA-1 and SHA-256 hash algorithms are supported now.
- DCHECK(hash_alg_ == SHA1 || hash_alg_ == SHA256);
-}
-
-bool HMAC::Init(const unsigned char* key, int key_length) {
- // Init must not be called more than once on the same HMAC object.
- DCHECK(plat_->key.empty());
-
- plat_->key.assign(key, key + key_length);
- return true;
-}
-
-HMAC::~HMAC() {
- // Zero out key copy.
- plat_->key.assign(plat_->key.size(), 0);
- STLClearObject(&plat_->key);
-}
-
-bool HMAC::Sign(const std::string& data,
- unsigned char* digest,
- int digest_length) {
- DCHECK_GE(digest_length, 0);
- DCHECK(!plat_->key.empty()); // Init must be called before Sign.
-
- ScopedOpenSSLSafeSizeBuffer<EVP_MAX_MD_SIZE> result(digest, digest_length);
- return ::HMAC(hash_alg_ == SHA1 ? EVP_sha1() : EVP_sha256(),
- &plat_->key[0], plat_->key.size(),
- reinterpret_cast<const unsigned char*>(data.data()),
- data.size(),
- result.safe_buffer(), NULL);
-}
-
-} // namespace base
diff --git a/base/hmac_unittest.cc b/base/hmac_unittest.cc
deleted file mode 100644
index 480c771..0000000
--- a/base/hmac_unittest.cc
+++ /dev/null
@@ -1,236 +0,0 @@
-// 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.
-
-#include <string>
-
-#include "base/hmac.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-static const int kSHA1DigestSize = 20;
-static const int kSHA256DigestSize = 32;
-
-TEST(HMACTest, HmacSafeBrowsingResponseTest) {
- const int kKeySize = 16;
-
- // Client key.
- const unsigned char kClientKey[kKeySize] =
- { 0xbf, 0xf6, 0x83, 0x4b, 0x3e, 0xa3, 0x23, 0xdd,
- 0x96, 0x78, 0x70, 0x8e, 0xa1, 0x9d, 0x3b, 0x40 };
-
- // Expected HMAC result using kMessage and kClientKey.
- const unsigned char kReceivedHmac[kSHA1DigestSize] =
- { 0xb9, 0x3c, 0xd6, 0xf0, 0x49, 0x47, 0xe2, 0x52,
- 0x59, 0x7a, 0xbd, 0x1f, 0x2b, 0x4c, 0x83, 0xad,
- 0x86, 0xd2, 0x48, 0x85 };
-
- const char kMessage[] =
-"n:1896\ni:goog-malware-shavar\nu:s.ytimg.com/safebrowsing/rd/goog-malware-shav"
-"ar_s_445-450\nu:s.ytimg.com/safebrowsing/rd/goog-malware-shavar_s_439-444\nu:s"
-".ytimg.com/safebrowsing/rd/goog-malware-shavar_s_437\nu:s.ytimg.com/safebrowsi"
-"ng/rd/goog-malware-shavar_s_436\nu:s.ytimg.com/safebrowsing/rd/goog-malware-sh"
-"avar_s_433-435\nu:s.ytimg.com/safebrowsing/rd/goog-malware-shavar_s_431\nu:s.y"
-"timg.com/safebrowsing/rd/goog-malware-shavar_s_430\nu:s.ytimg.com/safebrowsing"
-"/rd/goog-malware-shavar_s_429\nu:s.ytimg.com/safebrowsing/rd/goog-malware-shav"
-"ar_s_428\nu:s.ytimg.com/safebrowsing/rd/goog-malware-shavar_s_426\nu:s.ytimg.c"
-"om/safebrowsing/rd/goog-malware-shavar_s_424\nu:s.ytimg.com/safebrowsing/rd/go"
-"og-malware-shavar_s_423\nu:s.ytimg.com/safebrowsing/rd/goog-malware-shavar_s_4"
-"22\nu:s.ytimg.com/safebrowsing/rd/goog-malware-shavar_s_420\nu:s.ytimg.com/saf"
-"ebrowsing/rd/goog-malware-shavar_s_419\nu:s.ytimg.com/safebrowsing/rd/goog-mal"
-"ware-shavar_s_414\nu:s.ytimg.com/safebrowsing/rd/goog-malware-shavar_s_409-411"
-"\nu:s.ytimg.com/safebrowsing/rd/goog-malware-shavar_s_405\nu:s.ytimg.com/safeb"
-"rowsing/rd/goog-malware-shavar_s_404\nu:s.ytimg.com/safebrowsing/rd/goog-malwa"
-"re-shavar_s_402\nu:s.ytimg.com/safebrowsing/rd/goog-malware-shavar_s_401\nu:s."
-"ytimg.com/safebrowsing/rd/goog-malware-shavar_a_973-978\nu:s.ytimg.com/safebro"
-"wsing/rd/goog-malware-shavar_a_937-972\nu:s.ytimg.com/safebrowsing/rd/goog-mal"
-"ware-shavar_a_931-936\nu:s.ytimg.com/safebrowsing/rd/goog-malware-shavar_a_925"
-"-930\nu:s.ytimg.com/safebrowsing/rd/goog-malware-shavar_a_919-924\ni:goog-phis"
-"h-shavar\nu:s.ytimg.com/safebrowsing/rd/goog-phish-shavar_a_2633\nu:s.ytimg.co"
-"m/safebrowsing/rd/goog-phish-shavar_a_2632\nu:s.ytimg.com/safebrowsing/rd/goog"
-"-phish-shavar_a_2629-2631\nu:s.ytimg.com/safebrowsing/rd/goog-phish-shavar_a_2"
-"626-2628\nu:s.ytimg.com/safebrowsing/rd/goog-phish-shavar_a_2625\n";
-
- std::string message_data(kMessage);
-
- base::HMAC hmac(base::HMAC::SHA1);
- ASSERT_TRUE(hmac.Init(kClientKey, kKeySize));
- unsigned char calculated_hmac[kSHA1DigestSize];
-
- EXPECT_TRUE(hmac.Sign(message_data, calculated_hmac, kSHA1DigestSize));
- EXPECT_EQ(0, memcmp(kReceivedHmac, calculated_hmac, kSHA1DigestSize));
-}
-
-// Test cases from RFC 2202 section 3
-TEST(HMACTest, RFC2202TestCases) {
- const struct {
- const char *key;
- const int key_len;
- const char *data;
- const int data_len;
- const char *digest;
- } cases[] = {
- { "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B"
- "\x0B\x0B\x0B\x0B", 20,
- "Hi There", 8,
- "\xB6\x17\x31\x86\x55\x05\x72\x64\xE2\x8B\xC0\xB6\xFB\x37\x8C\x8E"
- "\xF1\x46\xBE\x00" },
- { "Jefe", 4,
- "what do ya want for nothing?", 28,
- "\xEF\xFC\xDF\x6A\xE5\xEB\x2F\xA2\xD2\x74\x16\xD5\xF1\x84\xDF\x9C"
- "\x25\x9A\x7C\x79" },
- { "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
- "\xAA\xAA\xAA\xAA", 20,
- "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
- "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
- "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
- "\xDD\xDD", 50,
- "\x12\x5D\x73\x42\xB9\xAC\x11\xCD\x91\xA3\x9A\xF4\x8A\xA1\x7B\x4F"
- "\x63\xF1\x75\xD3" },
- { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10"
- "\x11\x12\x13\x14\x15\x16\x17\x18\x19", 25,
- "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
- "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
- "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
- "\xCD\xCD", 50,
- "\x4C\x90\x07\xF4\x02\x62\x50\xC6\xBC\x84\x14\xF9\xBF\x50\xC8\x6C"
- "\x2D\x72\x35\xDA" },
- { "\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C"
- "\x0C\x0C\x0C\x0C", 20,
- "Test With Truncation", 20,
- "\x4C\x1A\x03\x42\x4B\x55\xE0\x7F\xE7\xF2\x7B\xE1\xD5\x8B\xB9\x32"
- "\x4A\x9A\x5A\x04" },
- { "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
- "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
- "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
- "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
- "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA",
- 80,
- "Test Using Larger Than Block-Size Key - Hash Key First", 54,
- "\xAA\x4A\xE5\xE1\x52\x72\xD0\x0E\x95\x70\x56\x37\xCE\x8A\x3B\x55"
- "\xED\x40\x21\x12" },
- { "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
- "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
- "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
- "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
- "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA",
- 80,
- "Test Using Larger Than Block-Size Key and Larger "
- "Than One Block-Size Data", 73,
- "\xE8\xE9\x9D\x0F\x45\x23\x7D\x78\x6D\x6B\xBA\xA7\x96\x5C\x78\x08"
- "\xBB\xFF\x1A\x91" }
- };
-
- for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
- base::HMAC hmac(base::HMAC::SHA1);
- ASSERT_TRUE(hmac.Init(reinterpret_cast<const unsigned char*>(cases[i].key),
- cases[i].key_len));
- std::string data_string(cases[i].data, cases[i].data_len);
- unsigned char digest[kSHA1DigestSize];
- EXPECT_TRUE(hmac.Sign(data_string, digest, kSHA1DigestSize));
- EXPECT_EQ(0, memcmp(cases[i].digest, digest, kSHA1DigestSize));
- }
-}
-
-// TODO(wtc): add other test vectors from RFC 4231.
-TEST(HMACTest, RFC4231TestCase6) {
- unsigned char key[131];
- for (size_t i = 0; i < sizeof(key); ++i)
- key[i] = 0xaa;
-
- std::string data = "Test Using Larger Than Block-Size Key - Hash Key First";
- ASSERT_EQ(54U, data.size());
-
- static unsigned char kKnownHMACSHA256[] = {
- 0x60, 0xe4, 0x31, 0x59, 0x1e, 0xe0, 0xb6, 0x7f,
- 0x0d, 0x8a, 0x26, 0xaa, 0xcb, 0xf5, 0xb7, 0x7f,
- 0x8e, 0x0b, 0xc6, 0x21, 0x37, 0x28, 0xc5, 0x14,
- 0x05, 0x46, 0x04, 0x0f, 0x0e, 0xe3, 0x7f, 0x54
- };
-
- base::HMAC hmac(base::HMAC::SHA256);
- ASSERT_TRUE(hmac.Init(key, sizeof(key)));
- unsigned char calculated_hmac[kSHA256DigestSize];
-
- EXPECT_TRUE(hmac.Sign(data, calculated_hmac, kSHA256DigestSize));
- EXPECT_EQ(0, memcmp(kKnownHMACSHA256, calculated_hmac, kSHA256DigestSize));
-}
-
-// Based on NSS's FIPS HMAC power-up self-test.
-TEST(HMACTest, NSSFIPSPowerUpSelfTest) {
- static const char kKnownMessage[] =
- "The test message for the MD2, MD5, and SHA-1 hashing algorithms.";
-
- static const unsigned char kKnownSecretKey[] = {
- 0x46, 0x69, 0x72, 0x65, 0x66, 0x6f, 0x78, 0x20,
- 0x61, 0x6e, 0x64, 0x20, 0x54, 0x68, 0x75, 0x6e,
- 0x64, 0x65, 0x72, 0x42, 0x69, 0x72, 0x64, 0x20,
- 0x61, 0x72, 0x65, 0x20, 0x61, 0x77, 0x65, 0x73,
- 0x6f, 0x6d, 0x65, 0x21, 0x00
- };
-
- static const size_t kKnownSecretKeySize = sizeof(kKnownSecretKey);
-
- // HMAC-SHA-1 known answer (20 bytes).
- static const unsigned char kKnownHMACSHA1[] = {
- 0xd5, 0x85, 0xf6, 0x5b, 0x39, 0xfa, 0xb9, 0x05,
- 0x3b, 0x57, 0x1d, 0x61, 0xe7, 0xb8, 0x84, 0x1e,
- 0x5d, 0x0e, 0x1e, 0x11
- };
-
- // HMAC-SHA-256 known answer (32 bytes).
- static const unsigned char kKnownHMACSHA256[] = {
- 0x05, 0x75, 0x9a, 0x9e, 0x70, 0x5e, 0xe7, 0x44,
- 0xe2, 0x46, 0x4b, 0x92, 0x22, 0x14, 0x22, 0xe0,
- 0x1b, 0x92, 0x8a, 0x0c, 0xfe, 0xf5, 0x49, 0xe9,
- 0xa7, 0x1b, 0x56, 0x7d, 0x1d, 0x29, 0x40, 0x48
- };
-
- std::string message_data(kKnownMessage);
-
- base::HMAC hmac(base::HMAC::SHA1);
- ASSERT_TRUE(hmac.Init(kKnownSecretKey, kKnownSecretKeySize));
- unsigned char calculated_hmac[kSHA1DigestSize];
-
- EXPECT_TRUE(hmac.Sign(message_data, calculated_hmac, kSHA1DigestSize));
- EXPECT_EQ(0, memcmp(kKnownHMACSHA1, calculated_hmac, kSHA1DigestSize));
-
- base::HMAC hmac2(base::HMAC::SHA256);
- ASSERT_TRUE(hmac2.Init(kKnownSecretKey, kKnownSecretKeySize));
- unsigned char calculated_hmac2[kSHA256DigestSize];
-
- EXPECT_TRUE(hmac2.Sign(message_data, calculated_hmac2, kSHA256DigestSize));
- EXPECT_EQ(0, memcmp(kKnownHMACSHA256, calculated_hmac2, kSHA256DigestSize));
-}
-
-TEST(HMACTest, HMACObjectReuse) {
- const char *key =
- "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
- "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
- "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
- "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
- "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA";
- const int key_len = 80;
-
- const struct {
- const char *data;
- const int data_len;
- const char *digest;
- } cases[] = {
- { "Test Using Larger Than Block-Size Key - Hash Key First", 54,
- "\xAA\x4A\xE5\xE1\x52\x72\xD0\x0E\x95\x70\x56\x37\xCE\x8A\x3B\x55"
- "\xED\x40\x21\x12" },
- { "Test Using Larger Than Block-Size Key and Larger "
- "Than One Block-Size Data", 73,
- "\xE8\xE9\x9D\x0F\x45\x23\x7D\x78\x6D\x6B\xBA\xA7\x96\x5C\x78\x08"
- "\xBB\xFF\x1A\x91" }
- };
-
- base::HMAC hmac(base::HMAC::SHA1);
- ASSERT_TRUE(hmac.Init(reinterpret_cast<const unsigned char*>(key), key_len));
- for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
- std::string data_string(cases[i].data, cases[i].data_len);
- unsigned char digest[kSHA1DigestSize];
- EXPECT_TRUE(hmac.Sign(data_string, digest, kSHA1DigestSize));
- EXPECT_EQ(0, memcmp(cases[i].digest, digest, kSHA1DigestSize));
- }
-}
diff --git a/base/hmac_win.cc b/base/hmac_win.cc
deleted file mode 100644
index a1c8225..0000000
--- a/base/hmac_win.cc
+++ /dev/null
@@ -1,197 +0,0 @@
-// 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.
-
-#include "base/hmac.h"
-
-#include <windows.h>
-#include <wincrypt.h>
-
-#include <algorithm>
-#include <vector>
-
-#include "base/crypto/scoped_capi_types.h"
-#include "base/logging.h"
-#include "base/third_party/nss/blapi.h"
-#include "base/third_party/nss/sha256.h"
-
-namespace base {
-
-namespace {
-
-// Implementation of HMAC-SHA-256:
-//
-// SHA-256 is supported in Windows XP SP3 or later. We still need to support
-// Windows XP SP2, so unfortunately we have to implement HMAC-SHA-256 here.
-
-enum {
- SHA256_BLOCK_SIZE = 64 // Block size (in bytes) of the input to SHA-256.
-};
-
-// See FIPS 198: The Keyed-Hash Message Authentication Code (HMAC).
-void ComputeHMACSHA256(const unsigned char* key, size_t key_len,
- const unsigned char* text, size_t text_len,
- unsigned char* output, size_t output_len) {
- SHA256Context ctx;
-
- // Pre-process the key, if necessary.
- unsigned char key0[SHA256_BLOCK_SIZE];
- if (key_len > SHA256_BLOCK_SIZE) {
- SHA256_Begin(&ctx);
- SHA256_Update(&ctx, key, key_len);
- SHA256_End(&ctx, key0, NULL, SHA256_LENGTH);
- memset(key0 + SHA256_LENGTH, 0, SHA256_BLOCK_SIZE - SHA256_LENGTH);
- } else {
- memcpy(key0, key, key_len);
- memset(key0 + key_len, 0, SHA256_BLOCK_SIZE - key_len);
- }
-
- unsigned char padded_key[SHA256_BLOCK_SIZE];
- unsigned char inner_hash[SHA256_LENGTH];
-
- // XOR key0 with ipad.
- for (int i = 0; i < SHA256_BLOCK_SIZE; ++i)
- padded_key[i] = key0[i] ^ 0x36;
-
- // Compute the inner hash.
- SHA256_Begin(&ctx);
- SHA256_Update(&ctx, padded_key, SHA256_BLOCK_SIZE);
- SHA256_Update(&ctx, text, text_len);
- SHA256_End(&ctx, inner_hash, NULL, SHA256_LENGTH);
-
- // XOR key0 with opad.
- for (int i = 0; i < SHA256_BLOCK_SIZE; ++i)
- padded_key[i] = key0[i] ^ 0x5c;
-
- // Compute the outer hash.
- SHA256_Begin(&ctx);
- SHA256_Update(&ctx, padded_key, SHA256_BLOCK_SIZE);
- SHA256_Update(&ctx, inner_hash, SHA256_LENGTH);
- SHA256_End(&ctx, output, NULL, output_len);
-}
-
-} // namespace
-
-struct HMACPlatformData {
- ~HMACPlatformData() {
- if (!raw_key_.empty()) {
- SecureZeroMemory(&raw_key_[0], raw_key_.size());
- }
-
- // Destroy the key before releasing the provider.
- key_.reset();
- }
-
- ScopedHCRYPTPROV provider_;
- ScopedHCRYPTKEY key_;
-
- // For HMAC-SHA-256 only.
- std::vector<unsigned char> raw_key_;
-};
-
-HMAC::HMAC(HashAlgorithm hash_alg)
- : hash_alg_(hash_alg), plat_(new HMACPlatformData()) {
- // Only SHA-1 and SHA-256 hash algorithms are supported now.
- DCHECK(hash_alg_ == SHA1 || hash_alg_ == SHA256);
-}
-
-bool HMAC::Init(const unsigned char* key, int key_length) {
- if (plat_->provider_ || plat_->key_ || !plat_->raw_key_.empty()) {
- // Init must not be called more than once on the same HMAC object.
- NOTREACHED();
- return false;
- }
-
- if (hash_alg_ == SHA256) {
- if (key_length < SHA256_LENGTH / 2)
- return false; // Key is too short.
- plat_->raw_key_.assign(key, key + key_length);
- return true;
- }
-
- if (!CryptAcquireContext(plat_->provider_.receive(), NULL, NULL,
- PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) {
- NOTREACHED();
- return false;
- }
-
- // This code doesn't work on Win2k because PLAINTEXTKEYBLOB and
- // CRYPT_IPSEC_HMAC_KEY are not supported on Windows 2000. PLAINTEXTKEYBLOB
- // allows the import of an unencrypted key. For Win2k support, a cubmbersome
- // exponent-of-one key procedure must be used:
- // http://support.microsoft.com/kb/228786/en-us
- // CRYPT_IPSEC_HMAC_KEY allows keys longer than 16 bytes.
-
- struct KeyBlob {
- BLOBHEADER header;
- DWORD key_size;
- BYTE key_data[1];
- };
- size_t key_blob_size = std::max(offsetof(KeyBlob, key_data) + key_length,
- sizeof(KeyBlob));
- std::vector<BYTE> key_blob_storage = std::vector<BYTE>(key_blob_size);
- KeyBlob* key_blob = reinterpret_cast<KeyBlob*>(&key_blob_storage[0]);
- key_blob->header.bType = PLAINTEXTKEYBLOB;
- key_blob->header.bVersion = CUR_BLOB_VERSION;
- key_blob->header.reserved = 0;
- key_blob->header.aiKeyAlg = CALG_RC2;
- key_blob->key_size = key_length;
- memcpy(key_blob->key_data, key, key_length);
-
- if (!CryptImportKey(plat_->provider_, &key_blob_storage[0],
- key_blob_storage.size(), 0, CRYPT_IPSEC_HMAC_KEY,
- plat_->key_.receive())) {
- NOTREACHED();
- return false;
- }
-
- // Destroy the copy of the key.
- SecureZeroMemory(key_blob->key_data, key_length);
-
- return true;
-}
-
-HMAC::~HMAC() {
-}
-
-bool HMAC::Sign(const std::string& data,
- unsigned char* digest,
- int digest_length) {
- if (hash_alg_ == SHA256) {
- if (plat_->raw_key_.empty())
- return false;
- ComputeHMACSHA256(&plat_->raw_key_[0], plat_->raw_key_.size(),
- reinterpret_cast<const unsigned char*>(data.data()),
- data.size(), digest, digest_length);
- return true;
- }
-
- if (!plat_->provider_ || !plat_->key_)
- return false;
-
- if (hash_alg_ != SHA1) {
- NOTREACHED();
- return false;
- }
-
- ScopedHCRYPTHASH hash;
- if (!CryptCreateHash(plat_->provider_, CALG_HMAC, plat_->key_, 0,
- hash.receive()))
- return false;
-
- HMAC_INFO hmac_info;
- memset(&hmac_info, 0, sizeof(hmac_info));
- hmac_info.HashAlgid = CALG_SHA1;
- if (!CryptSetHashParam(hash, HP_HMAC_INFO,
- reinterpret_cast<BYTE*>(&hmac_info), 0))
- return false;
-
- if (!CryptHashData(hash, reinterpret_cast<const BYTE*>(data.data()),
- static_cast<DWORD>(data.size()), 0))
- return false;
-
- DWORD sha1_size = digest_length;
- return !!CryptGetHashParam(hash, HP_HASHVAL, digest, &sha1_size, 0);
-}
-
-} // namespace base
diff --git a/base/i18n/break_iterator.cc b/base/i18n/break_iterator.cc
index e1b5e29..edc8950 100644
--- a/base/i18n/break_iterator.cc
+++ b/base/i18n/break_iterator.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -33,7 +33,7 @@ bool BreakIterator::Init() {
case BREAK_WORD:
break_type = UBRK_WORD;
break;
- case BREAK_SPACE:
+ case BREAK_LINE:
case BREAK_NEWLINE:
break_type = UBRK_LINE;
break;
@@ -59,7 +59,7 @@ bool BreakIterator::Advance() {
prev_ = pos_;
switch (break_type_) {
case BREAK_WORD:
- case BREAK_SPACE:
+ case BREAK_LINE:
pos = ubrk_next(static_cast<UBreakIterator*>(iter_));
if (pos == UBRK_DONE) {
pos_ = npos;
diff --git a/base/i18n/break_iterator.h b/base/i18n/break_iterator.h
index 9de7ac7..f64a1e1 100644
--- a/base/i18n/break_iterator.h
+++ b/base/i18n/break_iterator.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -12,19 +12,28 @@
// The BreakIterator class iterates through the words, word breaks, and
// line breaks in a UTF-16 string.
//
-// It provides several modes, BREAK_WORD, BREAK_SPACE, and BREAK_NEWLINE,
+// It provides several modes, BREAK_WORD, BREAK_LINE, and BREAK_NEWLINE,
// which modify how characters are aggregated into the returned string.
//
// Under BREAK_WORD mode, once a word is encountered any non-word
// characters are not included in the returned string (e.g. in the
// UTF-16 equivalent of the string " foo bar! ", the word breaks are at
// the periods in ". .foo. .bar.!. .").
+// Note that Chinese/Japanese/Thai do not use spaces between words so that
+// boundaries can fall in the middle of a continuous run of non-space /
+// non-punctuation characters.
//
-// Under BREAK_SPACE mode, once a word is encountered, any non-word
-// characters are included in the returned string, breaking only when a
-// space-equivalent character is encountered (e.g. in the
-// UTF16-equivalent of the string " foo bar! ", the word breaks are at
-// the periods in ". .foo .bar! .").
+// Under BREAK_LINE mode, once a line breaking opportunity is encountered,
+// any non-word characters are included in the returned string, breaking
+// only when a space-equivalent character or a line breaking opportunity
+// is encountered (e.g. in the UTF16-equivalent of the string " foo bar! ",
+// the breaks are at the periods in ". .foo .bar! .").
+//
+// Note that lines can be broken at any character/syllable/grapheme cluster
+// boundary in Chinese/Japanese/Korean and at word boundaries in Thai
+// (Thai does not use spaces between words). Therefore, this is NOT the same
+// as breaking only at space-equivalent characters where its former
+// name (BREAK_SPACE) implied.
//
// Under BREAK_NEWLINE mode, all characters are included in the returned
// string, breking only when a newline-equivalent character is encountered
@@ -48,7 +57,11 @@ class BreakIterator {
public:
enum BreakType {
BREAK_WORD,
- BREAK_SPACE,
+ BREAK_LINE,
+ // TODO(jshin): Remove this after reviewing call sites.
+ // If call sites really need break only on space-like characters
+ // implement it separately.
+ BREAK_SPACE = BREAK_LINE,
BREAK_NEWLINE,
};
@@ -75,7 +88,7 @@ class BreakIterator {
// Under BREAK_WORD mode, returns true if the break we just hit is the
// end of a word. (Otherwise, the break iterator just skipped over e.g.
- // whitespace or punctuation.) Under BREAK_SPACE and BREAK_NEWLINE modes,
+ // whitespace or punctuation.) Under BREAK_LINE and BREAK_NEWLINE modes,
// this distinction doesn't apply and it always retuns false.
bool IsWord() const;
diff --git a/base/i18n/file_util_icu.cc b/base/i18n/file_util_icu.cc
index ba69da0..9d12097 100644
--- a/base/i18n/file_util_icu.cc
+++ b/base/i18n/file_util_icu.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -8,8 +8,8 @@
#include "base/file_path.h"
#include "base/logging.h"
-#include "base/scoped_ptr.h"
-#include "base/singleton.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/singleton.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "base/sys_string_conversions.h"
diff --git a/base/i18n/file_util_icu_unittest.cc b/base/i18n/file_util_icu_unittest.cc
index 1da8a93..6c5d34d 100644
--- a/base/i18n/file_util_icu_unittest.cc
+++ b/base/i18n/file_util_icu_unittest.cc
@@ -1,11 +1,10 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
#include "base/i18n/file_util_icu.h"
#include "base/file_util.h"
-#include "base/path_service.h"
#include "base/utf_string_conversions.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/platform_test.h"
@@ -13,26 +12,6 @@
// file_util winds up using autoreleased objects on the Mac, so this needs
// to be a PlatformTest
class FileUtilICUTest : public PlatformTest {
- protected:
- virtual void SetUp() {
- PlatformTest::SetUp();
- // Name a subdirectory of the temp directory.
- ASSERT_TRUE(PathService::Get(base::DIR_TEMP, &test_dir_));
- test_dir_ = test_dir_.Append(FILE_PATH_LITERAL("FileUtilTest"));
-
- // Create a fresh, empty copy of this directory.
- file_util::Delete(test_dir_, true);
- file_util::CreateDirectory(test_dir_);
- }
- virtual void TearDown() {
- PlatformTest::TearDown();
- // Clean up test directory
- ASSERT_TRUE(file_util::Delete(test_dir_, true));
- ASSERT_FALSE(file_util::PathExists(test_dir_));
- }
-
- // the path to temporary directory used to contain the test operations
- FilePath test_dir_;
};
#if defined(OS_POSIX) && !defined(OS_MACOSX)
diff --git a/base/i18n/icu_encoding_detection.cc b/base/i18n/icu_encoding_detection.cc
index d579af2..2081c7a 100644
--- a/base/i18n/icu_encoding_detection.cc
+++ b/base/i18n/icu_encoding_detection.cc
@@ -1,9 +1,11 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
#include "base/i18n/icu_encoding_detection.h"
+#include <set>
+
#include "base/string_util.h"
#include "unicode/ucsdet.h"
@@ -20,6 +22,8 @@ bool DetectEncoding(const std::string& text, std::string* encoding) {
ucsdet_setText(detector, text.data(), static_cast<int32_t>(text.length()),
&status);
const UCharsetMatch* match = ucsdet_detect(detector, &status);
+ if (match == NULL)
+ return false;
const char* detected_encoding = ucsdet_getName(match, &status);
ucsdet_close(detector);
@@ -45,6 +49,13 @@ bool DetectAllEncodings(const std::string& text,
return false;
}
+ // ICU has some heuristics for encoding detection, such that the more likely
+ // encodings should be returned first. However, it doesn't always return
+ // all encodings that properly decode |text|, so we'll append more encodings
+ // later. To make that efficient, keep track of encodings sniffed in this
+ // first phase.
+ std::set<std::string> sniffed_encodings;
+
encodings->clear();
for (int i = 0; i < matches_count; i++) {
UErrorCode get_name_status = U_ZERO_ERROR;
@@ -54,8 +65,37 @@ bool DetectAllEncodings(const std::string& text,
if (U_FAILURE(get_name_status))
continue;
+ int32_t confidence = ucsdet_getConfidence(matches[i], &get_name_status);
+
+ // We also treat this error as non-fatal.
+ if (U_FAILURE(get_name_status))
+ continue;
+
+ // A confidence level >= 10 means that the encoding is expected to properly
+ // decode the text. Drop all encodings with lower confidence level.
+ if (confidence < 10)
+ continue;
+
encodings->push_back(encoding_name);
+ sniffed_encodings.insert(encoding_name);
+ }
+
+ // Append all encodings not included earlier, in arbitrary order.
+ // TODO(jshin): This shouldn't be necessary, possible ICU bug.
+ // See also http://crbug.com/65917.
+ UEnumeration* detectable_encodings = ucsdet_getAllDetectableCharsets(detector,
+ &status);
+ int detectable_count = uenum_count(detectable_encodings, &status);
+ for (int i = 0; i < detectable_count; i++) {
+ int name_length;
+ const char* name_raw = uenum_next(detectable_encodings,
+ &name_length,
+ &status);
+ std::string name(name_raw, name_length);
+ if (sniffed_encodings.find(name) == sniffed_encodings.end())
+ encodings->push_back(name);
}
+ uenum_close(detectable_encodings);
ucsdet_close(detector);
return !encodings->empty();
diff --git a/base/i18n/icu_encoding_detection.h b/base/i18n/icu_encoding_detection.h
index cdc4cb7..06c2567 100644
--- a/base/i18n/icu_encoding_detection.h
+++ b/base/i18n/icu_encoding_detection.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -18,6 +18,8 @@ bool DetectEncoding(const std::string& text, std::string* encoding);
// Detect all possible encodings of |text| and put their names
// (as returned by ICU) in |encodings|. Returns true on success.
+// Note: this function may return encodings that may fail to decode |text|,
+// the caller is responsible for handling that.
bool DetectAllEncodings(const std::string& text,
std::vector<std::string>* encodings);
diff --git a/base/i18n/icu_util.cc b/base/i18n/icu_util.cc
index eb7a688..4f17f17 100644
--- a/base/i18n/icu_util.cc
+++ b/base/i18n/icu_util.cc
@@ -44,7 +44,7 @@
#elif ICU_UTIL_DATA_IMPL == ICU_UTIL_DATA_SHARED
#define ICU_UTIL_DATA_SYMBOL "icudt" U_ICU_VERSION_SHORT "_dat"
#if defined(OS_WIN)
-#define ICU_UTIL_DATA_SHARED_MODULE_NAME "icudt" U_ICU_VERSION_SHORT ".dll"
+#define ICU_UTIL_DATA_SHARED_MODULE_NAME "icudt.dll"
#endif
#endif
diff --git a/base/i18n/number_formatting.cc b/base/i18n/number_formatting.cc
index df6af14..6b28de5 100644
--- a/base/i18n/number_formatting.cc
+++ b/base/i18n/number_formatting.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -7,7 +7,7 @@
#include "base/format_macros.h"
#include "base/logging.h"
#include "base/lazy_instance.h"
-#include "base/scoped_ptr.h"
+#include "base/memory/scoped_ptr.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "unicode/numfmt.h"
diff --git a/base/i18n/rtl_unittest.cc b/base/i18n/rtl_unittest.cc
index 061e140..3ee8254 100644
--- a/base/i18n/rtl_unittest.cc
+++ b/base/i18n/rtl_unittest.cc
@@ -4,9 +4,12 @@
#include "base/i18n/rtl.h"
+#include <algorithm>
+
#include "base/file_path.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
+#include "base/sys_string_conversions.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/platform_test.h"
@@ -115,88 +118,53 @@ TEST_F(RTLTest, GetFirstStrongCharacterDirection) {
base::i18n::GetFirstStrongCharacterDirection(string));
}
-typedef struct {
- std::wstring path;
- std::wstring wrapped_path;
-} PathAndWrappedPath;
-
TEST_F(RTLTest, WrapPathWithLTRFormatting) {
- std::wstring kSeparator;
- kSeparator.push_back(static_cast<wchar_t>(FilePath::kSeparators[0]));
- const PathAndWrappedPath test_data[] = {
+ const wchar_t* kTestData[] = {
// Test common path, such as "c:\foo\bar".
- { L"c:" + kSeparator + L"foo" + kSeparator + L"bar",
- L"\x202a"L"c:" + kSeparator + L"foo" + kSeparator +
- L"bar\x202c"
- },
+ L"c:/foo/bar",
// Test path with file name, such as "c:\foo\bar\test.jpg".
- { L"c:" + kSeparator + L"foo" + kSeparator + L"bar" + kSeparator +
- L"test.jpg",
- L"\x202a"L"c:" + kSeparator + L"foo" + kSeparator +
- L"bar" + kSeparator + L"test.jpg\x202c"
- },
+ L"c:/foo/bar/test.jpg",
// Test path ending with punctuation, such as "c:\(foo)\bar.".
- { L"c:" + kSeparator + L"(foo)" + kSeparator + L"bar.",
- L"\x202a"L"c:" + kSeparator + L"(foo)" + kSeparator +
- L"bar.\x202c"
- },
+ L"c:/(foo)/bar.",
// Test path ending with separator, such as "c:\foo\bar\".
- { L"c:" + kSeparator + L"foo" + kSeparator + L"bar" + kSeparator,
- L"\x202a"L"c:" + kSeparator + L"foo" + kSeparator +
- L"bar" + kSeparator + L"\x202c",
- },
+ L"c:/foo/bar/",
// Test path with RTL character.
- { L"c:" + kSeparator + L"\x05d0",
- L"\x202a"L"c:" + kSeparator + L"\x05d0\x202c",
- },
+ L"c:/\x05d0",
// Test path with 2 level RTL directory names.
- { L"c:" + kSeparator + L"\x05d0" + kSeparator + L"\x0622",
- L"\x202a"L"c:" + kSeparator + L"\x05d0" + kSeparator +
- L"\x0622\x202c",
- },
+ L"c:/\x05d0/\x0622",
// Test path with mixed RTL/LTR directory names and ending with punctuation.
- { L"c:" + kSeparator + L"\x05d0" + kSeparator + L"\x0622" + kSeparator +
- L"(foo)" + kSeparator + L"b.a.r.",
- L"\x202a"L"c:" + kSeparator + L"\x05d0" + kSeparator +
- L"\x0622" + kSeparator + L"(foo)" + kSeparator +
- L"b.a.r.\x202c",
- },
+ L"c:/\x05d0/\x0622/(foo)/b.a.r.",
// Test path without driver name, such as "/foo/bar/test/jpg".
- { kSeparator + L"foo" + kSeparator + L"bar" + kSeparator + L"test.jpg",
- L"\x202a" + kSeparator + L"foo" + kSeparator + L"bar" +
- kSeparator + L"test.jpg" + L"\x202c"
- },
+ L"/foo/bar/test.jpg",
// Test path start with current directory, such as "./foo".
- { L"." + kSeparator + L"foo",
- L"\x202a"L"." + kSeparator + L"foo" + L"\x202c"
- },
+ L"./foo",
// Test path start with parent directory, such as "../foo/bar.jpg".
- { L".." + kSeparator + L"foo" + kSeparator + L"bar.jpg",
- L"\x202a"L".." + kSeparator + L"foo" + kSeparator +
- L"bar.jpg" + L"\x202c"
- },
+ L"../foo/bar.jpg",
// Test absolute path, such as "//foo/bar.jpg".
- { kSeparator + kSeparator + L"foo" + kSeparator + L"bar.jpg",
- L"\x202a" + kSeparator + kSeparator + L"foo" + kSeparator +
- L"bar.jpg" + L"\x202c"
- },
+ L"//foo/bar.jpg",
// Test path with mixed RTL/LTR directory names.
- { L"c:" + kSeparator + L"foo" + kSeparator + L"\x05d0" + kSeparator +
- L"\x0622" + kSeparator + L"\x05d1.jpg",
- L"\x202a"L"c:" + kSeparator + L"foo" + kSeparator + L"\x05d0" +
- kSeparator + L"\x0622" + kSeparator + L"\x05d1.jpg" + L"\x202c",
- },
+ L"c:/foo/\x05d0/\x0622/\x05d1.jpg",
// Test empty path.
- { L"",
- L"\x202a\x202c"
- }
+ L""
};
- for (unsigned int i = 0; i < arraysize(test_data); ++i) {
+ for (unsigned int i = 0; i < arraysize(kTestData); ++i) {
+ FilePath path;
+#if defined(OS_WIN)
+ std::wstring win_path(kTestData[i]);
+ std::replace(win_path.begin(), win_path.end(), '/', '\\');
+ path = FilePath(win_path);
+ std::wstring wrapped_expected =
+ std::wstring(L"\x202a") + win_path + L"\x202c";
+#else
+ path = FilePath(base::SysWideToNativeMB(kTestData[i]));
+ std::wstring wrapped_expected =
+ std::wstring(L"\x202a") + kTestData[i] + L"\x202c";
+#endif
string16 localized_file_path_string;
- FilePath path = FilePath::FromWStringHack(test_data[i].path);
base::i18n::WrapPathWithLTRFormatting(path, &localized_file_path_string);
- std::wstring wrapped_path = UTF16ToWide(localized_file_path_string);
- EXPECT_EQ(wrapped_path, test_data[i].wrapped_path);
+
+ std::wstring wrapped_actual = UTF16ToWide(localized_file_path_string);
+ EXPECT_EQ(wrapped_expected, wrapped_actual);
}
}
diff --git a/base/i18n/time_formatting.cc b/base/i18n/time_formatting.cc
index 3fa984a..e52bd22 100644
--- a/base/i18n/time_formatting.cc
+++ b/base/i18n/time_formatting.cc
@@ -1,14 +1,16 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
#include "base/i18n/time_formatting.h"
#include "base/logging.h"
-#include "base/scoped_ptr.h"
+#include "base/memory/scoped_ptr.h"
#include "base/utf_string_conversions.h"
#include "base/time.h"
#include "unicode/datefmt.h"
+#include "unicode/dtptngen.h"
+#include "unicode/smpdtfmt.h"
using base::Time;
@@ -36,6 +38,34 @@ string16 TimeFormatTimeOfDay(const Time& time) {
return TimeFormat(formatter.get(), time);
}
+string16 TimeFormatTimeOfDayWithHourClockType(const Time& time,
+ HourClockType type) {
+ // Just redirect to the normal function if the default type matches the
+ // given type.
+ HourClockType default_type = GetHourClockType();
+ if (default_type == type) {
+ return TimeFormatTimeOfDay(time);
+ }
+
+ // Generate a locale-dependent format pattern. The generator will take
+ // care of locale-dependent formatting issues like which separator to
+ // use (some locales use '.' instead of ':'), and where to put the am/pm
+ // marker.
+ UErrorCode status = U_ZERO_ERROR;
+ icu::DateTimePatternGenerator *generator =
+ icu::DateTimePatternGenerator::createInstance(status);
+ CHECK(U_SUCCESS(status));
+ const char* base_pattern = (type == k12HourClock ? "ahm" : "Hm");
+ icu::UnicodeString generated_pattern =
+ generator->getBestPattern(icu::UnicodeString(base_pattern), status);
+ CHECK(U_SUCCESS(status));
+
+ // Then, format the time using the generated pattern.
+ icu::SimpleDateFormat formatter(generated_pattern, status);
+ CHECK(U_SUCCESS(status));
+ return TimeFormat(&formatter, time);
+}
+
string16 TimeFormatShortDate(const Time& time) {
scoped_ptr<icu::DateFormat> formatter(
icu::DateFormat::createDateInstance(icu::DateFormat::kMedium));
@@ -66,4 +96,44 @@ string16 TimeFormatFriendlyDate(const Time& time) {
return TimeFormat(formatter.get(), time);
}
+HourClockType GetHourClockType() {
+ // TODO(satorux,jshin): Rework this with ures_getByKeyWithFallback()
+ // once it becomes public. The short time format can be found at
+ // "calendar/gregorian/DateTimePatterns/3" in the resources.
+ scoped_ptr<icu::SimpleDateFormat> formatter(
+ static_cast<icu::SimpleDateFormat*>(
+ icu::DateFormat::createTimeInstance(icu::DateFormat::kShort)));
+ // Retrieve the short time format.
+ icu::UnicodeString pattern_unicode;
+ formatter->toPattern(pattern_unicode);
+
+ // Determine what hour clock type the current locale uses, by checking
+ // "a" (am/pm marker) in the short time format. This is reliable as "a"
+ // is used by all of 12-hour clock formats, but not any of 24-hour clock
+ // formats, as shown below.
+ //
+ // % grep -A4 DateTimePatterns third_party/icu/source/data/locales/*.txt |
+ // grep -B1 -- -- |grep -v -- '--' |
+ // perl -nle 'print $1 if /^\S+\s+"(.*)"/' |sort -u
+ //
+ // H.mm
+ // H:mm
+ // HH.mm
+ // HH:mm
+ // a h:mm
+ // ah:mm
+ // ahh:mm
+ // h-mm a
+ // h:mm a
+ // hh:mm a
+ //
+ // See http://userguide.icu-project.org/formatparse/datetime for details
+ // about the date/time format syntax.
+ if (pattern_unicode.indexOf('a') == -1) {
+ return k24HourClock;
+ } else {
+ return k12HourClock;
+ }
+}
+
} // namespace base
diff --git a/base/i18n/time_formatting.h b/base/i18n/time_formatting.h
index e70ad3d..99d1911 100644
--- a/base/i18n/time_formatting.h
+++ b/base/i18n/time_formatting.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -15,9 +15,21 @@ namespace base {
class Time;
+// Argument type used to specify the hour clock type.
+enum HourClockType {
+ k12HourClock, // Uses 1-12. e.g., "3:07 PM"
+ k24HourClock, // Uses 0-23. e.g., "15:07"
+};
+
// Returns the time of day, e.g., "3:07 PM".
string16 TimeFormatTimeOfDay(const Time& time);
+// Returns the time of day in the specified hour clock type. e.g.
+// "3:07 PM" (type == k12HourClock).
+// "15:07" (type == k24HourClock).
+string16 TimeFormatTimeOfDayWithHourClockType(const Time& time,
+ HourClockType type);
+
// Returns a shortened date, e.g. "Nov 7, 2007"
string16 TimeFormatShortDate(const Time& time);
@@ -36,6 +48,11 @@ string16 TimeFormatFriendlyDateAndTime(const Time& time);
// "Monday, March 6, 2008".
string16 TimeFormatFriendlyDate(const Time& time);
+// Gets the hour clock type of the current locale. e.g.
+// k12HourClock (en-US).
+// k24HourClock (en-GB).
+HourClockType GetHourClockType();
+
} // namespace base
#endif // BASE_I18N_TIME_FORMATTING_H_
diff --git a/base/json/json_reader.cc b/base/json/json_reader.cc
index c8fe78d..82bc7d4 100644
--- a/base/json/json_reader.cc
+++ b/base/json/json_reader.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -6,7 +6,7 @@
#include "base/float_util.h"
#include "base/logging.h"
-#include "base/scoped_ptr.h"
+#include "base/memory/scoped_ptr.h"
#include "base/string_number_conversions.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
diff --git a/base/json/json_reader.h b/base/json/json_reader.h
index a6f0686..4f83492 100644
--- a/base/json/json_reader.h
+++ b/base/json/json_reader.h
@@ -34,6 +34,7 @@
#include <string>
+#include "base/base_api.h"
#include "base/basictypes.h"
// Chromium and Chromium OS check out gtest to different places, so we're
@@ -46,7 +47,7 @@ class Value;
namespace base {
-class JSONReader {
+class BASE_API JSONReader {
public:
// A struct to hold a JS token.
class Token {
diff --git a/base/json/json_reader_unittest.cc b/base/json/json_reader_unittest.cc
index db0ab63..a7aeaf0 100644
--- a/base/json/json_reader_unittest.cc
+++ b/base/json/json_reader_unittest.cc
@@ -1,10 +1,10 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
#include "testing/gtest/include/gtest/gtest.h"
#include "base/json/json_reader.h"
-#include "base/scoped_ptr.h"
+#include "base/memory/scoped_ptr.h"
#include "base/string_piece.h"
#include "base/utf_string_conversions.h"
#include "base/values.h"
diff --git a/base/json/json_writer.h b/base/json/json_writer.h
index eb17145..c019e87 100644
--- a/base/json/json_writer.h
+++ b/base/json/json_writer.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -8,13 +8,14 @@
#include <string>
+#include "base/base_api.h"
#include "base/basictypes.h"
class Value;
namespace base {
-class JSONWriter {
+class BASE_API JSONWriter {
public:
// Given a root node, generates a JSON string and puts it into |json|.
// If |pretty_print| is true, return a slightly nicer formated json string
diff --git a/base/json/string_escape.h b/base/json/string_escape.h
index 2d7206b..e12e0bb 100644
--- a/base/json/string_escape.h
+++ b/base/json/string_escape.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
//
@@ -10,6 +10,7 @@
#include <string>
+#include "base/base_api.h"
#include "base/string16.h"
namespace base {
@@ -19,19 +20,19 @@ namespace base {
// If |put_in_quotes| is true, the result will be surrounded in double quotes.
// The outputted literal, when interpreted by the browser, should result in a
// javascript string that is identical and the same length as the input |str|.
-void JsonDoubleQuote(const std::string& str,
- bool put_in_quotes,
- std::string* dst);
+BASE_API void JsonDoubleQuote(const std::string& str,
+ bool put_in_quotes,
+ std::string* dst);
// Same as above, but always returns the result double quoted.
-std::string GetDoubleQuotedJson(const std::string& str);
+BASE_API std::string GetDoubleQuotedJson(const std::string& str);
-void JsonDoubleQuote(const string16& str,
- bool put_in_quotes,
- std::string* dst);
+BASE_API void JsonDoubleQuote(const string16& str,
+ bool put_in_quotes,
+ std::string* dst);
// Same as above, but always returns the result double quoted.
-std::string GetDoubleQuotedJson(const string16& str);
+BASE_API std::string GetDoubleQuotedJson(const string16& str);
} // namespace base
diff --git a/base/lazy_instance.h b/base/lazy_instance.h
index a22dbf3..7b1bdc4 100644
--- a/base/lazy_instance.h
+++ b/base/lazy_instance.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -39,6 +39,7 @@
#include <new> // For placement new.
#include "base/atomicops.h"
+#include "base/base_api.h"
#include "base/basictypes.h"
#include "base/third_party/dynamic_annotations/dynamic_annotations.h"
#include "base/threading/thread_restrictions.h"
@@ -80,7 +81,7 @@ void (*LeakyLazyInstanceTraits<Type>::Delete)(void* instance) = NULL;
// We pull out some of the functionality into a non-templated base, so that we
// can implement the more complicated pieces out of line in the .cc file.
-class LazyInstanceHelper {
+class BASE_API LazyInstanceHelper {
protected:
enum {
STATE_EMPTY = 0,
diff --git a/base/linux_util.cc b/base/linux_util.cc
index 4e7cc5c..2f9f862 100644
--- a/base/linux_util.cc
+++ b/base/linux_util.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -17,10 +17,10 @@
#include "base/command_line.h"
#include "base/file_util.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/singleton.h"
#include "base/path_service.h"
#include "base/process_util.h"
-#include "base/singleton.h"
-#include "base/scoped_ptr.h"
#include "base/string_util.h"
#include "base/synchronization/lock.h"
@@ -62,7 +62,7 @@ class LinuxDistroHelper {
// Indicate the check finished, move to STATE_CHECK_FINISHED.
void CheckFinished() {
base::AutoLock scoped_lock(lock_);
- DCHECK(state_ == STATE_CHECK_STARTED);
+ DCHECK_EQ(STATE_CHECK_STARTED, state_);
state_ = STATE_CHECK_FINISHED;
}
diff --git a/base/logging.cc b/base/logging.cc
index 57a2a89..430ae82 100644
--- a/base/logging.cc
+++ b/base/logging.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -39,10 +39,11 @@ typedef FILE* FileHandle;
typedef pthread_mutex_t* MutexHandle;
#endif
+#include <algorithm>
+#include <cstring>
#include <ctime>
#include <iomanip>
-#include <cstring>
-#include <algorithm>
+#include <ostream>
#include "base/base_switches.h"
#include "base/command_line.h"
@@ -821,3 +822,15 @@ void RawLog(int level, const char* message) {
std::ostream& operator<<(std::ostream& out, const wchar_t* wstr) {
return out << WideToUTF8(std::wstring(wstr));
}
+
+namespace base {
+
+// This was defined at the beginnig of this file.
+#undef write
+
+std::ostream& operator<<(std::ostream& o, const StringPiece& piece) {
+ o.write(piece.data(), static_cast<std::streamsize>(piece.size()));
+ return o;
+}
+
+} // namespace base
diff --git a/base/logging.h b/base/logging.h
index baf8eb6..0e78e1a 100644
--- a/base/logging.h
+++ b/base/logging.h
@@ -10,7 +10,9 @@
#include <cstring>
#include <sstream>
+#include "base/base_api.h"
#include "base/basictypes.h"
+#include "build/build_config.h"
//
// Optional message capabilities
@@ -190,11 +192,11 @@ typedef char PathChar;
// Implementation of the InitLogging() method declared below. We use a
// more-specific name so we can #define it above without affecting other code
// that has named stuff "InitLogging".
-bool BaseInitLoggingImpl(const PathChar* log_file,
- LoggingDestination logging_dest,
- LogLockingState lock_log,
- OldFileDeletionState delete_old,
- DcheckState dcheck_state);
+BASE_API bool BaseInitLoggingImpl(const PathChar* log_file,
+ LoggingDestination logging_dest,
+ LogLockingState lock_log,
+ OldFileDeletionState delete_old,
+ DcheckState dcheck_state);
// Sets the log file name and other global logging state. Calling this function
// is recommended, and is normally done at the beginning of application init.
@@ -221,19 +223,19 @@ inline bool InitLogging(const PathChar* log_file,
// up to level INFO) if this function is not called.
// Note that log messages for VLOG(x) are logged at level -x, so setting
// the min log level to negative values enables verbose logging.
-void SetMinLogLevel(int level);
+BASE_API void SetMinLogLevel(int level);
// Gets the current log level.
-int GetMinLogLevel();
+BASE_API int GetMinLogLevel();
// Gets the VLOG default verbosity level.
-int GetVlogVerbosity();
+BASE_API int GetVlogVerbosity();
// Gets the current vlog level for the given file (usually taken from
// __FILE__).
// Note that |N| is the size *with* the null terminator.
-int GetVlogLevelHelper(const char* file_start, size_t N);
+BASE_API int GetVlogLevelHelper(const char* file_start, size_t N);
template <size_t N>
int GetVlogLevel(const char (&file)[N]) {
@@ -244,27 +246,27 @@ int GetVlogLevel(const char (&file)[N]) {
// process and thread IDs default to off, the timestamp defaults to on.
// If this function is not called, logging defaults to writing the timestamp
// only.
-void SetLogItems(bool enable_process_id, bool enable_thread_id,
- bool enable_timestamp, bool enable_tickcount);
+BASE_API void SetLogItems(bool enable_process_id, bool enable_thread_id,
+ bool enable_timestamp, bool enable_tickcount);
// Sets whether or not you'd like to see fatal debug messages popped up in
// a dialog box or not.
// Dialogs are not shown by default.
-void SetShowErrorDialogs(bool enable_dialogs);
+BASE_API void SetShowErrorDialogs(bool enable_dialogs);
// Sets the Log Assert Handler that will be used to notify of check failures.
// The default handler shows a dialog box and then terminate the process,
// however clients can use this function to override with their own handling
// (e.g. a silent one for Unit Tests)
typedef void (*LogAssertHandlerFunction)(const std::string& str);
-void SetLogAssertHandler(LogAssertHandlerFunction handler);
+BASE_API void SetLogAssertHandler(LogAssertHandlerFunction handler);
// Sets the Log Report Handler that will be used to notify of check failures
// in non-debug mode. The default handler shows a dialog box and continues
// the execution, however clients can use this function to override with their
// own handling.
typedef void (*LogReportHandlerFunction)(const std::string& str);
-void SetLogReportHandler(LogReportHandlerFunction handler);
+BASE_API void SetLogReportHandler(LogReportHandlerFunction handler);
// Sets the Log Message Handler that gets passed every log message before
// it's sent to other log destinations (if any).
@@ -272,8 +274,8 @@ void SetLogReportHandler(LogReportHandlerFunction handler);
// should not be sent to other log destinations.
typedef bool (*LogMessageHandlerFunction)(int severity,
const char* file, int line, size_t message_start, const std::string& str);
-void SetLogMessageHandler(LogMessageHandlerFunction handler);
-LogMessageHandlerFunction GetLogMessageHandler();
+BASE_API void SetLogMessageHandler(LogMessageHandlerFunction handler);
+BASE_API LogMessageHandlerFunction GetLogMessageHandler();
typedef int LogSeverity;
const LogSeverity LOG_VERBOSE = -1; // This is level 1 verbosity
@@ -714,7 +716,7 @@ const LogSeverity LOG_DCHECK = LOG_INFO;
// You shouldn't actually use LogMessage's constructor to log things,
// though. You should use the LOG() macro (and variants thereof)
// above.
-class LogMessage {
+class BASE_API LogMessage {
public:
LogMessage(const char* file, int line, LogSeverity severity, int ctr);
@@ -792,7 +794,7 @@ inline void LogAtLevel(int const log_level, std::string const &msg) {
// This class is used to explicitly ignore values in the conditional
// logging macros. This avoids compiler warnings like "value computed
// is not used" and "statement has no effect".
-class LogMessageVoidify {
+class BASE_API LogMessageVoidify {
public:
LogMessageVoidify() { }
// This has to be an operator with a precedence lower than << but
@@ -808,11 +810,11 @@ typedef int SystemErrorCode;
// Alias for ::GetLastError() on Windows and errno on POSIX. Avoids having to
// pull in windows.h just for GetLastError() and DWORD.
-SystemErrorCode GetLastSystemErrorCode();
+BASE_API SystemErrorCode GetLastSystemErrorCode();
#if defined(OS_WIN)
// Appends a formatted system message of the GetLastError() type.
-class Win32ErrorLogMessage {
+class BASE_API Win32ErrorLogMessage {
public:
Win32ErrorLogMessage(const char* file,
int line,
@@ -864,10 +866,10 @@ class ErrnoLogMessage {
// NOTE: Since the log file is opened as necessary by the action of logging
// statements, there's no guarantee that it will stay closed
// after this call.
-void CloseLogFile();
+BASE_API void CloseLogFile();
// Async signal safe logging mechanism.
-void RawLog(int level, const char* message);
+BASE_API void RawLog(int level, const char* message);
#define RAW_LOG(level, message) logging::RawLog(logging::LOG_ ## level, message)
@@ -885,7 +887,7 @@ void RawLog(int level, const char* message);
// which is normally ASCII. It is relatively slow, so try not to use it for
// common cases. Non-ASCII characters will be converted to UTF-8 by these
// operators.
-std::ostream& operator<<(std::ostream& out, const wchar_t* wstr);
+BASE_API std::ostream& operator<<(std::ostream& out, const wchar_t* wstr);
inline std::ostream& operator<<(std::ostream& out, const std::wstring& wstr) {
return out << wstr.c_str();
}
@@ -936,8 +938,8 @@ namespace base {
class StringPiece;
-// allow StringPiece to be logged (needed for unit testing).
-extern std::ostream& operator<<(std::ostream& o, const StringPiece& piece);
+// Allows StringPiece to be logged.
+BASE_API std::ostream& operator<<(std::ostream& o, const StringPiece& piece);
} // namespace base
diff --git a/base/logging_unittest.cc b/base/logging_unittest.cc
index bb6e3d1..5a2cb53 100644
--- a/base/logging_unittest.cc
+++ b/base/logging_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -62,7 +62,10 @@ TEST_F(LoggingTest, BasicLogging) {
SetMinLogLevel(LOG_INFO);
EXPECT_TRUE(LOG_IS_ON(INFO));
- EXPECT_EQ(DEBUG_MODE != 0, DLOG_IS_ON(INFO));
+ // As of g++-4.5, the first argument to EXPECT_EQ cannot be a
+ // constant expression.
+ const bool kIsDebugMode = (DEBUG_MODE != 0);
+ EXPECT_EQ(kIsDebugMode, DLOG_IS_ON(INFO));
EXPECT_TRUE(VLOG_IS_ON(0));
LOG(INFO) << mock_log_source.Log();
diff --git a/base/logging_win.cc b/base/logging_win.cc
index f780b5e..a714665 100644
--- a/base/logging_win.cc
+++ b/base/logging_win.cc
@@ -1,9 +1,9 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
#include "base/logging_win.h"
-#include "base/singleton.h"
+#include "base/memory/singleton.h"
#include <initguid.h> // NOLINT
namespace logging {
diff --git a/base/logging_win.h b/base/logging_win.h
index 9058c84..bd69df9 100644
--- a/base/logging_win.h
+++ b/base/logging_win.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -7,6 +7,8 @@
#pragma once
#include <string>
+
+#include "base/base_api.h"
#include "base/basictypes.h"
#include "base/win/event_trace_provider.h"
#include "base/logging.h"
@@ -48,7 +50,7 @@ enum LogMessageTypes {
// Trace provider class to drive log control and transport
// with Event Tracing for Windows.
-class LogEventProvider : public base::win::EtwTraceProvider {
+class BASE_API LogEventProvider : public base::win::EtwTraceProvider {
public:
static LogEventProvider* GetInstance();
diff --git a/base/mac/OWNERS b/base/mac/OWNERS
new file mode 100644
index 0000000..a3fc32f
--- /dev/null
+++ b/base/mac/OWNERS
@@ -0,0 +1,2 @@
+mark@chromium.org
+thakis@chromium.org
diff --git a/base/mac/foundation_util.mm b/base/mac/foundation_util.mm
index 151d82f..3f41466 100644
--- a/base/mac/foundation_util.mm
+++ b/base/mac/foundation_util.mm
@@ -168,7 +168,7 @@ FilePath GetAppBundlePath(const FilePath& exec_name) {
// Don't prepend '/' to the first component.
std::vector<std::string>::const_iterator it = components.begin();
std::string bundle_name = *it;
- DCHECK(it->length() > 0);
+ DCHECK_GT(it->length(), 0U);
// If the first component ends in ".app", we're already done.
if (it->length() > kExtLength &&
!it->compare(it->length() - kExtLength, kExtLength, kExt, kExtLength))
@@ -181,7 +181,7 @@ FilePath GetAppBundlePath(const FilePath& exec_name) {
// Go through the remaining components.
for (++it; it != components.end(); ++it) {
- DCHECK(it->length() > 0);
+ DCHECK_GT(it->length(), 0U);
bundle_name += *it;
diff --git a/base/mac/mac_util.mm b/base/mac/mac_util.mm
index 2eddeae..2f93b23 100644
--- a/base/mac/mac_util.mm
+++ b/base/mac/mac_util.mm
@@ -9,7 +9,7 @@
#include "base/file_path.h"
#include "base/logging.h"
#include "base/mac/scoped_cftyperef.h"
-#include "base/scoped_nsobject.h"
+#include "base/memory/scoped_nsobject.h"
#include "base/sys_string_conversions.h"
namespace base {
@@ -17,7 +17,7 @@ namespace mac {
namespace {
-// a count of currently outstanding requests for full screen mode from browser
+// The current count of outstanding requests for full screen mode from browser
// windows, plugins, etc.
int g_full_screen_requests[kNumFullScreenModes] = { 0, 0, 0};
@@ -75,7 +75,7 @@ bool WasLaunchedAsLoginItem() {
}
// Looks into Shared File Lists corresponding to Login Items for the item
-// representing the current application. If such an item is found, returns
+// representing the current application. If such an item is found, returns a
// retained reference to it. Caller is responsible for releasing the reference.
LSSharedFileListItemRef GetLoginItemForApp() {
ScopedCFTypeRef<LSSharedFileListRef> login_items(LSSharedFileListCreate(
@@ -276,7 +276,7 @@ bool SetFileBackupExclusion(const FilePath& file_path, bool exclude) {
bool success =
CSBackupSetItemExcluded((CFURLRef)url, exclude, true) == noErr;
if (!success)
- LOG(WARNING) << "Failed to set backup excluson for file '"
+ LOG(WARNING) << "Failed to set backup exclusion for file '"
<< file_path.value().c_str() << "'. Continuing.";
return success;
}
diff --git a/base/mac/mac_util_unittest.mm b/base/mac/mac_util_unittest.mm
index bae0019..b4f9268 100644
--- a/base/mac/mac_util_unittest.mm
+++ b/base/mac/mac_util_unittest.mm
@@ -9,7 +9,7 @@
#include "base/file_path.h"
#include "base/file_util.h"
#include "base/mac/scoped_cftyperef.h"
-#include "base/scoped_nsobject.h"
+#include "base/memory/scoped_nsobject.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/platform_test.h"
diff --git a/base/mach_ipc_mac.h b/base/mach_ipc_mac.h
index d506a00..4e80f62 100644
--- a/base/mach_ipc_mac.h
+++ b/base/mach_ipc_mac.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -140,6 +140,7 @@ class MachMsgPortDescriptor : public mach_msg_port_descriptor_t {
//
class MachMessage {
public:
+ static const size_t kEmptyMessageSize;
virtual ~MachMessage();
@@ -209,7 +210,6 @@ class MachMessage {
// of the Mach header.
size_t MaxSize() const { return storage_length_bytes_; }
- protected:
mach_msg_header_t *Head() { return &(storage_->head); }
private:
@@ -220,15 +220,6 @@ class MachMessage {
u_int8_t padding[1024];
};
- // kEmptyMessageSize needs to have the definition of MachMessageData before
- // it.
- public:
- // The size of an empty message with no data.
- static const size_t kEmptyMessageSize = sizeof(mach_msg_header_t) +
- sizeof(mach_msg_body_t) +
- sizeof(MessageDataPacket);
-
- private:
MachMessageData *storage_;
size_t storage_length_bytes_;
bool own_storage_; // Is storage owned by this object?
diff --git a/base/mach_ipc_mac.mm b/base/mach_ipc_mac.mm
index a0bfdc8..b6dedd2 100644
--- a/base/mach_ipc_mac.mm
+++ b/base/mach_ipc_mac.mm
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -11,6 +11,10 @@
namespace base {
+// static
+const size_t MachMessage::kEmptyMessageSize = sizeof(mach_msg_header_t) +
+ sizeof(mach_msg_body_t) + sizeof(MessageDataPacket);
+
//==============================================================================
MachSendMessage::MachSendMessage(int32_t message_id) : MachMessage() {
Initialize(message_id);
@@ -50,7 +54,7 @@ MachMessage::MachMessage(void *storage, size_t storage_length)
storage_length_bytes_(storage_length),
own_storage_(false) {
DCHECK(storage);
- DCHECK(storage_length >= kEmptyMessageSize);
+ DCHECK_GE(storage_length, kEmptyMessageSize);
}
//==============================================================================
diff --git a/base/md5.h b/base/md5.h
index 5ab6e32..10e2a35 100644
--- a/base/md5.h
+++ b/base/md5.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -8,6 +8,8 @@
#include <string>
+#include "base/base_api.h"
+
// MD5 stands for Message Digest algorithm 5.
// MD5 is a robust hash function, designed for cyptography, but often used
// for file checksums. The code is complex and slow, but has few
@@ -42,25 +44,25 @@ typedef char MD5Context[88];
// Computes the MD5 sum of the given data buffer with the given length.
// The given 'digest' structure will be filled with the result data.
-void MD5Sum(const void* data, size_t length, MD5Digest* digest);
+BASE_API void MD5Sum(const void* data, size_t length, MD5Digest* digest);
// Initializes the given MD5 context structure for subsequent calls to
// MD5Update().
-void MD5Init(MD5Context* context);
+BASE_API void MD5Init(MD5Context* context);
// For the given buffer of data, updates the given MD5 context with the sum of
// the data. You can call this any number of times during the computation,
// except that MD5Init() must have been called first.
-void MD5Update(MD5Context* context, const void* buf, size_t len);
+BASE_API void MD5Update(MD5Context* context, const void* buf, size_t len);
// Finalizes the MD5 operation and fills the buffer with the digest.
-void MD5Final(MD5Digest* digest, MD5Context* pCtx);
+BASE_API void MD5Final(MD5Digest* digest, MD5Context* pCtx);
// Converts a digest into human-readable hexadecimal.
-std::string MD5DigestToBase16(const MD5Digest& digest);
+BASE_API std::string MD5DigestToBase16(const MD5Digest& digest);
// Returns the MD5 (in hexadecimal) of a string.
-std::string MD5String(const std::string& str);
+BASE_API std::string MD5String(const std::string& str);
#endif // BASE_MD5_H_
diff --git a/base/linked_ptr.h b/base/memory/linked_ptr.h
index 162798d..41931d8 100644
--- a/base/linked_ptr.h
+++ b/base/memory/linked_ptr.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
//
@@ -34,8 +34,8 @@
// - is thread safe for copying and deletion
// - supports weak_ptrs
-#ifndef BASE_LINKED_PTR_H_
-#define BASE_LINKED_PTR_H_
+#ifndef BASE_MEMORY_LINKED_PTR_H_
+#define BASE_MEMORY_LINKED_PTR_H_
#pragma once
#include "base/logging.h" // for CHECK macros
@@ -179,4 +179,4 @@ linked_ptr<T> make_linked_ptr(T* ptr) {
return linked_ptr<T>(ptr);
}
-#endif // BASE_LINKED_PTR_H_
+#endif // BASE_MEMORY_LINKED_PTR_H_
diff --git a/base/linked_ptr_unittest.cc b/base/memory/linked_ptr_unittest.cc
index e65b687..ae10fc2 100644
--- a/base/linked_ptr_unittest.cc
+++ b/base/memory/linked_ptr_unittest.cc
@@ -1,10 +1,10 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
#include <string>
-#include "base/linked_ptr.h"
+#include "base/memory/linked_ptr.h"
#include "base/stringprintf.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/base/memory_debug.cc b/base/memory/memory_debug.cc
index 7d048e6..f020b94 100644
--- a/base/memory_debug.cc
+++ b/base/memory/memory_debug.cc
@@ -1,8 +1,8 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
-#include "base/memory_debug.h"
+#include "base/memory/memory_debug.h"
#ifdef PURIFY
// this #define is used to prevent people from directly using pure.h
diff --git a/base/memory_debug.h b/base/memory/memory_debug.h
index 6d8c7f9..d094edb 100644
--- a/base/memory_debug.h
+++ b/base/memory/memory_debug.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -6,15 +6,16 @@
// All methods are effectively no-ops unless this program is being run through
// a supported memory tool (currently, only Purify)
-#ifndef BASE_MEMORY_DEBUG_H_
-#define BASE_MEMORY_DEBUG_H_
+#ifndef BASE_MEMORY_MEMORY_DEBUG_H_
+#define BASE_MEMORY_MEMORY_DEBUG_H_
#pragma once
+#include "base/base_api.h"
#include "base/basictypes.h"
namespace base {
-class MemoryDebug {
+class BASE_API MemoryDebug {
public:
// Since MIU messages are a lot of data, and we don't always want this data,
// we have a global switch. If disabled, *MemoryInUse are no-ops.
@@ -44,4 +45,4 @@ class MemoryDebug {
} // namespace base
-#endif // BASE_MEMORY_DEBUG_H_
+#endif // BASE_MEMORY_MEMORY_DEBUG_H_
diff --git a/base/raw_scoped_refptr_mismatch_checker.h b/base/memory/raw_scoped_refptr_mismatch_checker.h
index b79cfb5..a4a50c3 100644
--- a/base/raw_scoped_refptr_mismatch_checker.h
+++ b/base/memory/raw_scoped_refptr_mismatch_checker.h
@@ -1,12 +1,12 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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 BASE_RAW_SCOPED_REFPTR_MISMATCH_CHECKER_H_
-#define BASE_RAW_SCOPED_REFPTR_MISMATCH_CHECKER_H_
+#ifndef BASE_MEMORY_RAW_SCOPED_REFPTR_MISMATCH_CHECKER_H_
+#define BASE_MEMORY_RAW_SCOPED_REFPTR_MISMATCH_CHECKER_H_
#pragma once
-#include "base/ref_counted.h"
+#include "base/memory/ref_counted.h"
#include "base/template_util.h"
#include "base/tuple.h"
#include "build/build_config.h"
@@ -127,4 +127,4 @@ struct ParamsUseScopedRefptrCorrectly<Tuple8<A, B, C, D, E, F, G, H> > {
} // namespace base
-#endif // BASE_RAW_SCOPED_REFPTR_MISMATCH_CHECKER_H_
+#endif // BASE_MEMORY_RAW_SCOPED_REFPTR_MISMATCH_CHECKER_H_
diff --git a/base/ref_counted.cc b/base/memory/ref_counted.cc
index 2d459ae..31ad509 100644
--- a/base/ref_counted.cc
+++ b/base/memory/ref_counted.cc
@@ -1,8 +1,8 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
-#include "base/ref_counted.h"
+#include "base/memory/ref_counted.h"
#include "base/logging.h"
#include "base/threading/thread_collision_warner.h"
diff --git a/base/ref_counted.h b/base/memory/ref_counted.h
index 4c3aeb8..1207ed4 100644
--- a/base/ref_counted.h
+++ b/base/memory/ref_counted.h
@@ -1,19 +1,20 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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 BASE_REF_COUNTED_H_
-#define BASE_REF_COUNTED_H_
+#ifndef BASE_MEMORY_REF_COUNTED_H_
+#define BASE_MEMORY_REF_COUNTED_H_
#pragma once
#include "base/atomic_ref_count.h"
+#include "base/base_api.h"
#include "base/threading/thread_collision_warner.h"
namespace base {
namespace subtle {
-class RefCountedBase {
+class BASE_API RefCountedBase {
public:
static bool ImplementsThreadSafeReferenceCounting() { return false; }
@@ -39,7 +40,7 @@ class RefCountedBase {
DISALLOW_COPY_AND_ASSIGN(RefCountedBase);
};
-class RefCountedThreadSafeBase {
+class BASE_API RefCountedThreadSafeBase {
public:
static bool ImplementsThreadSafeReferenceCounting() { return true; }
@@ -295,4 +296,4 @@ scoped_refptr<T> make_scoped_refptr(T* t) {
return scoped_refptr<T>(t);
}
-#endif // BASE_REF_COUNTED_H_
+#endif // BASE_MEMORY_REF_COUNTED_H_
diff --git a/base/ref_counted_memory.cc b/base/memory/ref_counted_memory.cc
index dc244b9..aa16031 100644
--- a/base/ref_counted_memory.cc
+++ b/base/memory/ref_counted_memory.cc
@@ -1,8 +1,8 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
-#include "base/ref_counted_memory.h"
+#include "base/memory/ref_counted_memory.h"
RefCountedMemory::RefCountedMemory() {
}
diff --git a/base/ref_counted_memory.h b/base/memory/ref_counted_memory.h
index fe7427e..1a0f51e 100644
--- a/base/ref_counted_memory.h
+++ b/base/memory/ref_counted_memory.h
@@ -2,13 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef BASE_REF_COUNTED_MEMORY_H_
-#define BASE_REF_COUNTED_MEMORY_H_
+#ifndef BASE_MEMORY_REF_COUNTED_MEMORY_H_
+#define BASE_MEMORY_REF_COUNTED_MEMORY_H_
#pragma once
#include <vector>
-#include "base/ref_counted.h"
+#include "base/base_api.h"
+#include "base/memory/ref_counted.h"
// TODO(erg): The contents of this file should be in a namespace. This would
// require touching >100 files in chrome/ though.
@@ -16,7 +17,8 @@
// A generic interface to memory. This object is reference counted because one
// of its two subclasses own the data they carry, and we need to have
// heterogeneous containers of these two types of memory.
-class RefCountedMemory : public base::RefCountedThreadSafe<RefCountedMemory> {
+class BASE_API RefCountedMemory
+ : public base::RefCountedThreadSafe<RefCountedMemory> {
public:
// Retrieves a pointer to the beginning of the data we point to. If the data
// is empty, this will return NULL.
@@ -33,7 +35,7 @@ class RefCountedMemory : public base::RefCountedThreadSafe<RefCountedMemory> {
// An implementation of RefCountedMemory, where the ref counting does not
// matter.
-class RefCountedStaticMemory : public RefCountedMemory {
+class BASE_API RefCountedStaticMemory : public RefCountedMemory {
public:
RefCountedStaticMemory()
: data_(NULL), length_(0) {}
@@ -53,7 +55,7 @@ class RefCountedStaticMemory : public RefCountedMemory {
// An implementation of RefCountedMemory, where we own our the data in a
// vector.
-class RefCountedBytes : public RefCountedMemory {
+class BASE_API RefCountedBytes : public RefCountedMemory {
public:
RefCountedBytes();
@@ -79,4 +81,4 @@ class RefCountedBytes : public RefCountedMemory {
DISALLOW_COPY_AND_ASSIGN(RefCountedBytes);
};
-#endif // BASE_REF_COUNTED_MEMORY_H_
+#endif // BASE_MEMORY_REF_COUNTED_MEMORY_H_
diff --git a/base/ref_counted_unittest.cc b/base/memory/ref_counted_unittest.cc
index cd6f922..dcc292f 100644
--- a/base/ref_counted_unittest.cc
+++ b/base/memory/ref_counted_unittest.cc
@@ -1,9 +1,9 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
+#include "base/memory/ref_counted.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "base/ref_counted.h"
namespace {
diff --git a/base/scoped_callback_factory.h b/base/memory/scoped_callback_factory.h
index a2fc1f0..a9c58a0 100644
--- a/base/scoped_callback_factory.h
+++ b/base/memory/scoped_callback_factory.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -33,11 +33,11 @@
// callback runs, it will notice that the MyClass instance is dead, and it will
// avoid calling the GotData method.
-#ifndef BASE_SCOPED_CALLBACK_FACTORY_H_
-#define BASE_SCOPED_CALLBACK_FACTORY_H_
+#ifndef BASE_MEMORY_SCOPED_CALLBACK_FACTORY_H_
+#define BASE_MEMORY_SCOPED_CALLBACK_FACTORY_H_
#include "base/callback.h"
-#include "base/weak_ptr.h"
+#include "base/memory/weak_ptr.h"
namespace base {
@@ -130,4 +130,4 @@ class ScopedCallbackFactory {
} // namespace base
-#endif // BASE_SCOPED_CALLBACK_FACTORY_H_
+#endif // BASE_MEMORY_SCOPED_CALLBACK_FACTORY_H_
diff --git a/base/scoped_handle.h b/base/memory/scoped_handle.h
index 90cb5d5..232d83e 100644
--- a/base/scoped_handle.h
+++ b/base/memory/scoped_handle.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef BASE_SCOPED_HANDLE_H_
-#define BASE_SCOPED_HANDLE_H_
+#ifndef BASE_MEMORY_SCOPED_HANDLE_H_
+#define BASE_MEMORY_SCOPED_HANDLE_H_
#pragma once
#include <stdio.h>
@@ -48,4 +48,4 @@ class ScopedStdioHandle {
DISALLOW_COPY_AND_ASSIGN(ScopedStdioHandle);
};
-#endif // BASE_SCOPED_HANDLE_H_
+#endif // BASE_MEMORY_SCOPED_HANDLE_H_
diff --git a/base/scoped_native_library.cc b/base/memory/scoped_native_library.cc
index 9d34449..c1e6afc 100644
--- a/base/scoped_native_library.cc
+++ b/base/memory/scoped_native_library.cc
@@ -1,8 +1,8 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
-#include "base/scoped_native_library.h"
+#include "base/memory/scoped_native_library.h"
namespace base {
@@ -14,7 +14,7 @@ ScopedNativeLibrary::ScopedNativeLibrary(NativeLibrary library)
}
ScopedNativeLibrary::ScopedNativeLibrary(const FilePath& library_path) {
- library_ = base::LoadNativeLibrary(library_path);
+ library_ = base::LoadNativeLibrary(library_path, NULL);
}
ScopedNativeLibrary::~ScopedNativeLibrary() {
diff --git a/base/scoped_native_library.h b/base/memory/scoped_native_library.h
index 28b29b3..56116b9 100644
--- a/base/scoped_native_library.h
+++ b/base/memory/scoped_native_library.h
@@ -1,11 +1,12 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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 BASE_SCOPED_NATIVE_LIBRARY_H_
-#define BASE_SCOPED_NATIVE_LIBRARY_H_
+#ifndef BASE_MEMORY_SCOPED_NATIVE_LIBRARY_H_
+#define BASE_MEMORY_SCOPED_NATIVE_LIBRARY_H_
#pragma once
+#include "base/base_api.h"
#include "base/native_library.h"
class FilePath;
@@ -15,7 +16,7 @@ namespace base {
// A class which encapsulates a base::NativeLibrary object available only in a
// scope.
// This class automatically unloads the loaded library in its destructor.
-class ScopedNativeLibrary {
+class BASE_API ScopedNativeLibrary {
public:
// Initializes with a NULL library.
ScopedNativeLibrary();
@@ -49,4 +50,4 @@ class ScopedNativeLibrary {
} // namespace base
-#endif // BASE_SCOPED_NATIVE_LIBRARY_H_
+#endif // BASE_MEMORY_SCOPED_NATIVE_LIBRARY_H_
diff --git a/base/scoped_native_library_unittest.cc b/base/memory/scoped_native_library_unittest.cc
index 567239d..0cc60e2 100644
--- a/base/scoped_native_library_unittest.cc
+++ b/base/memory/scoped_native_library_unittest.cc
@@ -1,8 +1,8 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
-#include "base/scoped_native_library.h"
+#include "base/memory/scoped_native_library.h"
#if defined(OS_WIN)
#include "base/file_path.h"
#endif
diff --git a/base/scoped_nsobject.h b/base/memory/scoped_nsobject.h
index a9783e0..235ac39 100644
--- a/base/scoped_nsobject.h
+++ b/base/memory/scoped_nsobject.h
@@ -1,9 +1,9 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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 BASE_SCOPED_NSOBJECT_H_
-#define BASE_SCOPED_NSOBJECT_H_
+#ifndef BASE_MEMORY_SCOPED_NSOBJECT_H_
+#define BASE_MEMORY_SCOPED_NSOBJECT_H_
#pragma once
#import <Foundation/Foundation.h>
@@ -164,4 +164,4 @@ class scoped_nsobject<NSAutoreleasePool> {
DISALLOW_COPY_AND_ASSIGN(scoped_nsobject);
};
-#endif // BASE_SCOPED_NSOBJECT_H_
+#endif // BASE_MEMORY_SCOPED_NSOBJECT_H_
diff --git a/base/scoped_open_process.h b/base/memory/scoped_open_process.h
index 641f8e5..d5bdd95 100644
--- a/base/scoped_open_process.h
+++ b/base/memory/scoped_open_process.h
@@ -1,9 +1,9 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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 BASE_SCOPED_OPEN_PROCESS_H_
-#define BASE_SCOPED_OPEN_PROCESS_H_
+#ifndef BASE_MEMORY_SCOPED_OPEN_PROCESS_H_
+#define BASE_MEMORY_SCOPED_OPEN_PROCESS_H_
#pragma once
#include "base/process.h"
@@ -47,4 +47,4 @@ class ScopedOpenProcess {
};
} // namespace base
-#endif // BASE_SCOPED_OPEN_PROCESS_H_
+#endif // BASE_MEMORY_SCOPED_OPEN_PROCESS_H_
diff --git a/base/memory/scoped_ptr.h b/base/memory/scoped_ptr.h
new file mode 100644
index 0000000..1067d42
--- /dev/null
+++ b/base/memory/scoped_ptr.h
@@ -0,0 +1,383 @@
+// Copyright (c) 2011 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.
+
+// Scopers help you manage ownership of a pointer, helping you easily manage the
+// a pointer within a scope, and automatically destroying the pointer at the
+// end of a scope. There are two main classes you will use, which correspond
+// to the operators new/delete and new[]/delete[].
+//
+// Example usage (scoped_ptr):
+// {
+// scoped_ptr<Foo> foo(new Foo("wee"));
+// } // foo goes out of scope, releasing the pointer with it.
+//
+// {
+// scoped_ptr<Foo> foo; // No pointer managed.
+// foo.reset(new Foo("wee")); // Now a pointer is managed.
+// foo.reset(new Foo("wee2")); // Foo("wee") was destroyed.
+// foo.reset(new Foo("wee3")); // Foo("wee2") was destroyed.
+// foo->Method(); // Foo::Method() called.
+// foo.get()->Method(); // Foo::Method() called.
+// SomeFunc(foo.release()); // SomeFunc takes ownership, foo no longer
+// // manages a pointer.
+// foo.reset(new Foo("wee4")); // foo manages a pointer again.
+// foo.reset(); // Foo("wee4") destroyed, foo no longer
+// // manages a pointer.
+// } // foo wasn't managing a pointer, so nothing was destroyed.
+//
+// Example usage (scoped_array):
+// {
+// scoped_array<Foo> foo(new Foo[100]);
+// foo.get()->Method(); // Foo::Method on the 0th element.
+// foo[10].Method(); // Foo::Method on the 10th element.
+// }
+
+#ifndef BASE_MEMORY_SCOPED_PTR_H_
+#define BASE_MEMORY_SCOPED_PTR_H_
+#pragma once
+
+// This is an implementation designed to match the anticipated future TR2
+// implementation of the scoped_ptr class, and its closely-related brethren,
+// scoped_array, scoped_ptr_malloc.
+
+#include <assert.h>
+#include <stddef.h>
+#include <stdlib.h>
+
+#include "base/compiler_specific.h"
+
+// A scoped_ptr<T> is like a T*, except that the destructor of scoped_ptr<T>
+// automatically deletes the pointer it holds (if any).
+// That is, scoped_ptr<T> owns the T object that it points to.
+// Like a T*, a scoped_ptr<T> may hold either NULL or a pointer to a T object.
+// Also like T*, scoped_ptr<T> is thread-compatible, and once you
+// dereference it, you get the threadsafety guarantees of T.
+//
+// The size of a scoped_ptr is small:
+// sizeof(scoped_ptr<C>) == sizeof(C*)
+template <class C>
+class scoped_ptr {
+ public:
+
+ // The element type
+ typedef C element_type;
+
+ // Constructor. Defaults to initializing with NULL.
+ // There is no way to create an uninitialized scoped_ptr.
+ // The input parameter must be allocated with new.
+ explicit scoped_ptr(C* p = NULL) : ptr_(p) { }
+
+ // Destructor. If there is a C object, delete it.
+ // We don't need to test ptr_ == NULL because C++ does that for us.
+ ~scoped_ptr() {
+ enum { type_must_be_complete = sizeof(C) };
+ delete ptr_;
+ }
+
+ // Reset. Deletes the current owned object, if any.
+ // Then takes ownership of a new object, if given.
+ // this->reset(this->get()) works.
+ void reset(C* p = NULL) {
+ if (p != ptr_) {
+ enum { type_must_be_complete = sizeof(C) };
+ delete ptr_;
+ ptr_ = p;
+ }
+ }
+
+ // Accessors to get the owned object.
+ // operator* and operator-> will assert() if there is no current object.
+ C& operator*() const {
+ assert(ptr_ != NULL);
+ return *ptr_;
+ }
+ C* operator->() const {
+ assert(ptr_ != NULL);
+ return ptr_;
+ }
+ C* get() const { return ptr_; }
+
+ // Comparison operators.
+ // These return whether two scoped_ptr refer to the same object, not just to
+ // two different but equal objects.
+ bool operator==(C* p) const { return ptr_ == p; }
+ bool operator!=(C* p) const { return ptr_ != p; }
+
+ // Swap two scoped pointers.
+ void swap(scoped_ptr& p2) {
+ C* tmp = ptr_;
+ ptr_ = p2.ptr_;
+ p2.ptr_ = tmp;
+ }
+
+ // Release a pointer.
+ // The return value is the current pointer held by this object.
+ // If this object holds a NULL pointer, the return value is NULL.
+ // After this operation, this object will hold a NULL pointer,
+ // and will not own the object any more.
+ C* release() WARN_UNUSED_RESULT {
+ C* retVal = ptr_;
+ ptr_ = NULL;
+ return retVal;
+ }
+
+ private:
+ C* ptr_;
+
+ // Forbid comparison of scoped_ptr types. If C2 != C, it totally doesn't
+ // make sense, and if C2 == C, it still doesn't make sense because you should
+ // never have the same object owned by two different scoped_ptrs.
+ template <class C2> bool operator==(scoped_ptr<C2> const& p2) const;
+ template <class C2> bool operator!=(scoped_ptr<C2> const& p2) const;
+
+ // Disallow evil constructors
+ scoped_ptr(const scoped_ptr&);
+ void operator=(const scoped_ptr&);
+};
+
+// Free functions
+template <class C>
+void swap(scoped_ptr<C>& p1, scoped_ptr<C>& p2) {
+ p1.swap(p2);
+}
+
+template <class C>
+bool operator==(C* p1, const scoped_ptr<C>& p2) {
+ return p1 == p2.get();
+}
+
+template <class C>
+bool operator!=(C* p1, const scoped_ptr<C>& p2) {
+ return p1 != p2.get();
+}
+
+// scoped_array<C> is like scoped_ptr<C>, except that the caller must allocate
+// with new [] and the destructor deletes objects with delete [].
+//
+// As with scoped_ptr<C>, a scoped_array<C> either points to an object
+// or is NULL. A scoped_array<C> owns the object that it points to.
+// scoped_array<T> is thread-compatible, and once you index into it,
+// the returned objects have only the threadsafety guarantees of T.
+//
+// Size: sizeof(scoped_array<C>) == sizeof(C*)
+template <class C>
+class scoped_array {
+ public:
+
+ // The element type
+ typedef C element_type;
+
+ // Constructor. Defaults to intializing with NULL.
+ // There is no way to create an uninitialized scoped_array.
+ // The input parameter must be allocated with new [].
+ explicit scoped_array(C* p = NULL) : array_(p) { }
+
+ // Destructor. If there is a C object, delete it.
+ // We don't need to test ptr_ == NULL because C++ does that for us.
+ ~scoped_array() {
+ enum { type_must_be_complete = sizeof(C) };
+ delete[] array_;
+ }
+
+ // Reset. Deletes the current owned object, if any.
+ // Then takes ownership of a new object, if given.
+ // this->reset(this->get()) works.
+ void reset(C* p = NULL) {
+ if (p != array_) {
+ enum { type_must_be_complete = sizeof(C) };
+ delete[] array_;
+ array_ = p;
+ }
+ }
+
+ // Get one element of the current object.
+ // Will assert() if there is no current object, or index i is negative.
+ C& operator[](ptrdiff_t i) const {
+ assert(i >= 0);
+ assert(array_ != NULL);
+ return array_[i];
+ }
+
+ // Get a pointer to the zeroth element of the current object.
+ // If there is no current object, return NULL.
+ C* get() const {
+ return array_;
+ }
+
+ // Comparison operators.
+ // These return whether two scoped_array refer to the same object, not just to
+ // two different but equal objects.
+ bool operator==(C* p) const { return array_ == p; }
+ bool operator!=(C* p) const { return array_ != p; }
+
+ // Swap two scoped arrays.
+ void swap(scoped_array& p2) {
+ C* tmp = array_;
+ array_ = p2.array_;
+ p2.array_ = tmp;
+ }
+
+ // Release an array.
+ // The return value is the current pointer held by this object.
+ // If this object holds a NULL pointer, the return value is NULL.
+ // After this operation, this object will hold a NULL pointer,
+ // and will not own the object any more.
+ C* release() WARN_UNUSED_RESULT {
+ C* retVal = array_;
+ array_ = NULL;
+ return retVal;
+ }
+
+ private:
+ C* array_;
+
+ // Forbid comparison of different scoped_array types.
+ template <class C2> bool operator==(scoped_array<C2> const& p2) const;
+ template <class C2> bool operator!=(scoped_array<C2> const& p2) const;
+
+ // Disallow evil constructors
+ scoped_array(const scoped_array&);
+ void operator=(const scoped_array&);
+};
+
+// Free functions
+template <class C>
+void swap(scoped_array<C>& p1, scoped_array<C>& p2) {
+ p1.swap(p2);
+}
+
+template <class C>
+bool operator==(C* p1, const scoped_array<C>& p2) {
+ return p1 == p2.get();
+}
+
+template <class C>
+bool operator!=(C* p1, const scoped_array<C>& p2) {
+ return p1 != p2.get();
+}
+
+// This class wraps the c library function free() in a class that can be
+// passed as a template argument to scoped_ptr_malloc below.
+class ScopedPtrMallocFree {
+ public:
+ inline void operator()(void* x) const {
+ free(x);
+ }
+};
+
+// scoped_ptr_malloc<> is similar to scoped_ptr<>, but it accepts a
+// second template argument, the functor used to free the object.
+
+template<class C, class FreeProc = ScopedPtrMallocFree>
+class scoped_ptr_malloc {
+ public:
+
+ // The element type
+ typedef C element_type;
+
+ // Constructor. Defaults to initializing with NULL.
+ // There is no way to create an uninitialized scoped_ptr.
+ // The input parameter must be allocated with an allocator that matches the
+ // Free functor. For the default Free functor, this is malloc, calloc, or
+ // realloc.
+ explicit scoped_ptr_malloc(C* p = NULL): ptr_(p) {}
+
+ // Destructor. If there is a C object, call the Free functor.
+ ~scoped_ptr_malloc() {
+ free_(ptr_);
+ }
+
+ // Reset. Calls the Free functor on the current owned object, if any.
+ // Then takes ownership of a new object, if given.
+ // this->reset(this->get()) works.
+ void reset(C* p = NULL) {
+ if (ptr_ != p) {
+ free_(ptr_);
+ ptr_ = p;
+ }
+ }
+
+ // Get the current object.
+ // operator* and operator-> will cause an assert() failure if there is
+ // no current object.
+ C& operator*() const {
+ assert(ptr_ != NULL);
+ return *ptr_;
+ }
+
+ C* operator->() const {
+ assert(ptr_ != NULL);
+ return ptr_;
+ }
+
+ C* get() const {
+ return ptr_;
+ }
+
+ // Comparison operators.
+ // These return whether a scoped_ptr_malloc and a plain pointer refer
+ // to the same object, not just to two different but equal objects.
+ // For compatibility with the boost-derived implementation, these
+ // take non-const arguments.
+ bool operator==(C* p) const {
+ return ptr_ == p;
+ }
+
+ bool operator!=(C* p) const {
+ return ptr_ != p;
+ }
+
+ // Swap two scoped pointers.
+ void swap(scoped_ptr_malloc & b) {
+ C* tmp = b.ptr_;
+ b.ptr_ = ptr_;
+ ptr_ = tmp;
+ }
+
+ // Release a pointer.
+ // The return value is the current pointer held by this object.
+ // If this object holds a NULL pointer, the return value is NULL.
+ // After this operation, this object will hold a NULL pointer,
+ // and will not own the object any more.
+ C* release() WARN_UNUSED_RESULT {
+ C* tmp = ptr_;
+ ptr_ = NULL;
+ return tmp;
+ }
+
+ private:
+ C* ptr_;
+
+ // no reason to use these: each scoped_ptr_malloc should have its own object
+ template <class C2, class GP>
+ bool operator==(scoped_ptr_malloc<C2, GP> const& p) const;
+ template <class C2, class GP>
+ bool operator!=(scoped_ptr_malloc<C2, GP> const& p) const;
+
+ static FreeProc const free_;
+
+ // Disallow evil constructors
+ scoped_ptr_malloc(const scoped_ptr_malloc&);
+ void operator=(const scoped_ptr_malloc&);
+};
+
+template<class C, class FP>
+FP const scoped_ptr_malloc<C, FP>::free_ = FP();
+
+template<class C, class FP> inline
+void swap(scoped_ptr_malloc<C, FP>& a, scoped_ptr_malloc<C, FP>& b) {
+ a.swap(b);
+}
+
+template<class C, class FP> inline
+bool operator==(C* p, const scoped_ptr_malloc<C, FP>& b) {
+ return p == b.get();
+}
+
+template<class C, class FP> inline
+bool operator!=(C* p, const scoped_ptr_malloc<C, FP>& b) {
+ return p != b.get();
+}
+
+#endif // BASE_MEMORY_SCOPED_PTR_H_
diff --git a/base/scoped_ptr_unittest.cc b/base/memory/scoped_ptr_unittest.cc
index 99b1bc0..7519051 100644
--- a/base/scoped_ptr_unittest.cc
+++ b/base/memory/scoped_ptr_unittest.cc
@@ -1,9 +1,9 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
#include "base/basictypes.h"
-#include "base/scoped_ptr.h"
+#include "base/memory/scoped_ptr.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace {
diff --git a/base/scoped_temp_dir.cc b/base/memory/scoped_temp_dir.cc
index 000ed0a..f7db15d 100644
--- a/base/scoped_temp_dir.cc
+++ b/base/memory/scoped_temp_dir.cc
@@ -1,8 +1,8 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
-#include "base/scoped_temp_dir.h"
+#include "base/memory/scoped_temp_dir.h"
#include "base/file_util.h"
#include "base/logging.h"
diff --git a/base/scoped_temp_dir.h b/base/memory/scoped_temp_dir.h
index 4286d28..4c0a73f 100644
--- a/base/scoped_temp_dir.h
+++ b/base/memory/scoped_temp_dir.h
@@ -1,9 +1,9 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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 BASE_SCOPED_TEMP_DIR_H_
-#define BASE_SCOPED_TEMP_DIR_H_
+#ifndef BASE_MEMORY_SCOPED_TEMP_DIR_H_
+#define BASE_MEMORY_SCOPED_TEMP_DIR_H_
#pragma once
// An object representing a temporary / scratch directory that should be cleaned
@@ -16,9 +16,10 @@
// (CreateUniqueTempDir, CreateUniqueTempDirUnderPath, and Set) must have
// intervening calls to Delete or Take, or the calls will fail.
+#include "base/base_api.h"
#include "base/file_path.h"
-class ScopedTempDir {
+class BASE_API ScopedTempDir {
public:
// No directory is owned/created initially.
ScopedTempDir();
@@ -55,4 +56,4 @@ class ScopedTempDir {
DISALLOW_COPY_AND_ASSIGN(ScopedTempDir);
};
-#endif // BASE_SCOPED_TEMP_DIR_H_
+#endif // BASE_MEMORY_SCOPED_TEMP_DIR_H_
diff --git a/base/scoped_temp_dir_unittest.cc b/base/memory/scoped_temp_dir_unittest.cc
index 135c2fd..a83856f 100644
--- a/base/scoped_temp_dir_unittest.cc
+++ b/base/memory/scoped_temp_dir_unittest.cc
@@ -1,10 +1,10 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
#include "base/file_util.h"
+#include "base/memory/scoped_temp_dir.h"
#include "base/platform_file.h"
-#include "base/scoped_temp_dir.h"
#include "testing/gtest/include/gtest/gtest.h"
TEST(ScopedTempDir, FullPath) {
diff --git a/base/scoped_vector.h b/base/memory/scoped_vector.h
index 9d372f3..6e0cf05 100644
--- a/base/scoped_vector.h
+++ b/base/memory/scoped_vector.h
@@ -1,9 +1,9 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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 BASE_SCOPED_VECTOR_H_
-#define BASE_SCOPED_VECTOR_H_
+#ifndef BASE_MEMORY_SCOPED_VECTOR_H_
+#define BASE_MEMORY_SCOPED_VECTOR_H_
#pragma once
#include <vector>
@@ -62,6 +62,12 @@ class ScopedVector {
return v.insert(position, x);
}
+ // Lets the ScopedVector take ownership of elements in [first,last).
+ template<typename InputIterator>
+ void insert(iterator position, InputIterator first, InputIterator last) {
+ v.insert(position, first, last);
+ }
+
iterator erase(iterator position) {
delete *position;
return v.erase(position);
@@ -87,4 +93,4 @@ class ScopedVector {
DISALLOW_COPY_AND_ASSIGN(ScopedVector);
};
-#endif // BASE_SCOPED_VECTOR_H_
+#endif // BASE_MEMORY_SCOPED_VECTOR_H_
diff --git a/base/memory/scoped_vector_unittest.cc b/base/memory/scoped_vector_unittest.cc
new file mode 100644
index 0000000..d2f3d0a
--- /dev/null
+++ b/base/memory/scoped_vector_unittest.cc
@@ -0,0 +1,156 @@
+// Copyright (c) 2011 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.
+
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/scoped_vector.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace {
+
+// The LifeCycleObject notifies its Observer upon construction & destruction.
+class LifeCycleObject {
+ public:
+ class Observer {
+ public:
+ virtual void OnLifeCycleConstruct(LifeCycleObject* o) = 0;
+ virtual void OnLifeCycleDestroy(LifeCycleObject* o) = 0;
+
+ protected:
+ virtual ~Observer() {}
+ };
+
+ explicit LifeCycleObject(Observer* observer)
+ : observer_(observer) {
+ observer_->OnLifeCycleConstruct(this);
+ }
+
+ ~LifeCycleObject() {
+ observer_->OnLifeCycleDestroy(this);
+ }
+
+ private:
+ Observer* observer_;
+
+ DISALLOW_COPY_AND_ASSIGN(LifeCycleObject);
+};
+
+// The life cycle states we care about for the purposes of testing ScopedVector
+// against objects.
+enum LifeCycleState {
+ LC_INITIAL,
+ LC_CONSTRUCTED,
+ LC_DESTROYED,
+};
+
+// Because we wish to watch the life cycle of an object being constructed and
+// destroyed, and further wish to test expectations against the state of that
+// object, we cannot save state in that object itself. Instead, we use this
+// pairing of the watcher, which observes the object and notifies of
+// construction & destruction. Since we also may be testing assumptions about
+// things not getting freed, this class also acts like a scoping object and
+// deletes the |constructed_life_cycle_object_|, if any when the
+// LifeCycleWatcher is destroyed. To keep this simple, the only expected state
+// changes are:
+// INITIAL -> CONSTRUCTED -> DESTROYED.
+// Anything more complicated than that should start another test.
+class LifeCycleWatcher : public LifeCycleObject::Observer {
+ public:
+ LifeCycleWatcher()
+ : life_cycle_state_(LC_INITIAL),
+ constructed_life_cycle_object_(NULL) {}
+ ~LifeCycleWatcher() {
+ }
+
+ // Assert INITIAL -> CONSTRUCTED and no LifeCycleObject associated with this
+ // LifeCycleWatcher.
+ virtual void OnLifeCycleConstruct(LifeCycleObject* object) {
+ ASSERT_EQ(LC_INITIAL, life_cycle_state_);
+ ASSERT_EQ(NULL, constructed_life_cycle_object_.get());
+ life_cycle_state_ = LC_CONSTRUCTED;
+ constructed_life_cycle_object_.reset(object);
+ }
+
+ // Assert CONSTRUCTED -> DESTROYED and the |object| being destroyed is the
+ // same one we saw constructed.
+ virtual void OnLifeCycleDestroy(LifeCycleObject* object) {
+ ASSERT_EQ(LC_CONSTRUCTED, life_cycle_state_);
+ LifeCycleObject* constructed_life_cycle_object =
+ constructed_life_cycle_object_.release();
+ ASSERT_EQ(constructed_life_cycle_object, object);
+ life_cycle_state_ = LC_DESTROYED;
+ }
+
+ LifeCycleState life_cycle_state() const { return life_cycle_state_; }
+
+ // Factory method for creating a new LifeCycleObject tied to this
+ // LifeCycleWatcher.
+ LifeCycleObject* NewLifeCycleObject() {
+ return new LifeCycleObject(this);
+ }
+
+ private:
+ LifeCycleState life_cycle_state_;
+ scoped_ptr<LifeCycleObject> constructed_life_cycle_object_;
+
+ DISALLOW_COPY_AND_ASSIGN(LifeCycleWatcher);
+};
+
+TEST(ScopedVectorTest, LifeCycleWatcher) {
+ LifeCycleWatcher watcher;
+ EXPECT_EQ(LC_INITIAL, watcher.life_cycle_state());
+ LifeCycleObject* object = watcher.NewLifeCycleObject();
+ EXPECT_EQ(LC_CONSTRUCTED, watcher.life_cycle_state());
+ delete object;
+ EXPECT_EQ(LC_DESTROYED, watcher.life_cycle_state());
+}
+
+TEST(ScopedVectorTest, Reset) {
+ LifeCycleWatcher watcher;
+ EXPECT_EQ(LC_INITIAL, watcher.life_cycle_state());
+ ScopedVector<LifeCycleObject> scoped_vector;
+ scoped_vector.push_back(watcher.NewLifeCycleObject());
+ EXPECT_EQ(LC_CONSTRUCTED, watcher.life_cycle_state());
+ scoped_vector.reset();
+ EXPECT_EQ(LC_DESTROYED, watcher.life_cycle_state());
+}
+
+TEST(ScopedVectorTest, Scope) {
+ LifeCycleWatcher watcher;
+ EXPECT_EQ(LC_INITIAL, watcher.life_cycle_state());
+ {
+ ScopedVector<LifeCycleObject> scoped_vector;
+ scoped_vector.push_back(watcher.NewLifeCycleObject());
+ EXPECT_EQ(LC_CONSTRUCTED, watcher.life_cycle_state());
+ }
+ EXPECT_EQ(LC_DESTROYED, watcher.life_cycle_state());
+}
+
+TEST(ScopedVectorTest, InsertRange) {
+ LifeCycleWatcher watchers[5];
+
+ std::vector<LifeCycleObject*> vec;
+ for(LifeCycleWatcher* it = watchers; it != watchers + arraysize(watchers);
+ ++it) {
+ EXPECT_EQ(LC_INITIAL, it->life_cycle_state());
+ vec.push_back(it->NewLifeCycleObject());
+ EXPECT_EQ(LC_CONSTRUCTED, it->life_cycle_state());
+ }
+ // Start scope for ScopedVector.
+ {
+ ScopedVector<LifeCycleObject> scoped_vector;
+ scoped_vector.insert(scoped_vector.end(), vec.begin() + 1, vec.begin() + 3);
+ for(LifeCycleWatcher* it = watchers; it != watchers + arraysize(watchers);
+ ++it)
+ EXPECT_EQ(LC_CONSTRUCTED, it->life_cycle_state());
+ }
+ for(LifeCycleWatcher* it = watchers; it != watchers + 1; ++it)
+ EXPECT_EQ(LC_CONSTRUCTED, it->life_cycle_state());
+ for(LifeCycleWatcher* it = watchers + 1; it != watchers + 3; ++it)
+ EXPECT_EQ(LC_DESTROYED, it->life_cycle_state());
+ for(LifeCycleWatcher* it = watchers + 3; it != watchers + arraysize(watchers);
+ ++it)
+ EXPECT_EQ(LC_CONSTRUCTED, it->life_cycle_state());
+}
+
+} // namespace
diff --git a/base/singleton.h b/base/memory/singleton.h
index 0fe5e27..a387356 100644
--- a/base/singleton.h
+++ b/base/memory/singleton.h
@@ -1,9 +1,9 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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 BASE_SINGLETON_H_
-#define BASE_SINGLETON_H_
+#ifndef BASE_MEMORY_SINGLETON_H_
+#define BASE_MEMORY_SINGLETON_H_
#pragma once
#include "base/at_exit.h"
@@ -126,7 +126,7 @@ template <typename Type> base::subtle::Atomic32
// Example usage:
//
// In your header:
-// #include "base/singleton.h"
+// #include "base/memory/singleton.h"
// class FooClass {
// public:
// static FooClass* GetInstance(); <-- See comment below on this.
@@ -268,4 +268,4 @@ template <typename Type, typename Traits, typename DifferentiatingType>
base::subtle::AtomicWord Singleton<Type, Traits, DifferentiatingType>::
instance_ = 0;
-#endif // BASE_SINGLETON_H_
+#endif // BASE_MEMORY_SINGLETON_H_
diff --git a/base/singleton_objc.h b/base/memory/singleton_objc.h
index e28c8a5..8531556 100644
--- a/base/singleton_objc.h
+++ b/base/memory/singleton_objc.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -27,12 +27,12 @@
// ...
// Foo* widgetSingleton = SingletonObjC<Foo, FooSingletonTraits>::get();
-#ifndef BASE_SINGLETON_OBJC_H_
-#define BASE_SINGLETON_OBJC_H_
+#ifndef BASE_MEMORY_SINGLETON_OBJC_H_
+#define BASE_MEMORY_SINGLETON_OBJC_H_
#pragma once
#import <Foundation/Foundation.h>
-#include "base/singleton.h"
+#include "base/memory/singleton.h"
// Singleton traits usable to manage traditional Objective-C objects, which
// are instantiated by sending |alloc| and |init| messages, and are deallocated
@@ -58,4 +58,4 @@ template<typename Type,
class SingletonObjC : public Singleton<Type, Traits, DifferentiatingType> {
};
-#endif // BASE_SINGLETON_OBJC_H_
+#endif // BASE_MEMORY_SINGLETON_OBJC_H_
diff --git a/base/singleton_unittest.cc b/base/memory/singleton_unittest.cc
index 3d7e7e6..a605885 100644
--- a/base/singleton_unittest.cc
+++ b/base/memory/singleton_unittest.cc
@@ -1,11 +1,11 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
#include "base/at_exit.h"
#include "base/file_util.h"
+#include "base/memory/singleton.h"
#include "base/path_service.h"
-#include "base/singleton.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace {
diff --git a/base/weak_ptr.cc b/base/memory/weak_ptr.cc
index 86c89c1..30c777c 100644
--- a/base/weak_ptr.cc
+++ b/base/memory/weak_ptr.cc
@@ -1,8 +1,8 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
-#include "base/weak_ptr.h"
+#include "base/memory/weak_ptr.h"
namespace base {
namespace internal {
@@ -10,19 +10,19 @@ namespace internal {
WeakReference::Flag::Flag(Flag** handle) : handle_(handle) {
}
-WeakReference::Flag::~Flag() {
- if (handle_)
- *handle_ = NULL;
+void WeakReference::Flag::Invalidate() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ handle_ = NULL;
}
-void WeakReference::Flag::AddRef() const {
- DCHECK(CalledOnValidThread());
- RefCounted<Flag>::AddRef();
+bool WeakReference::Flag::IsValid() const {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ return handle_ != NULL;
}
-void WeakReference::Flag::Release() const {
- DCHECK(CalledOnValidThread());
- RefCounted<Flag>::Release();
+WeakReference::Flag::~Flag() {
+ if (handle_)
+ *handle_ = NULL;
}
WeakReference::WeakReference() {
@@ -35,7 +35,7 @@ WeakReference::~WeakReference() {
}
bool WeakReference::is_valid() const {
- return flag_ && flag_->is_valid();
+ return flag_ && flag_->IsValid();
}
WeakReferenceOwner::WeakReferenceOwner() : flag_(NULL) {
diff --git a/base/weak_ptr.h b/base/memory/weak_ptr.h
index 6168367..0c6b4a7 100644
--- a/base/weak_ptr.h
+++ b/base/memory/weak_ptr.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -48,13 +48,14 @@
// WARNING: weak pointers are not threadsafe!!! You must only use a WeakPtr
// instance on thread where it was created.
-#ifndef BASE_WEAK_PTR_H_
-#define BASE_WEAK_PTR_H_
+#ifndef BASE_MEMORY_WEAK_PTR_H_
+#define BASE_MEMORY_WEAK_PTR_H_
#pragma once
+#include "base/base_api.h"
#include "base/logging.h"
-#include "base/ref_counted.h"
-#include "base/threading/non_thread_safe.h"
+#include "base/memory/ref_counted.h"
+#include "base/threading/thread_checker.h"
namespace base {
@@ -62,21 +63,25 @@ namespace internal {
// These classes are part of the WeakPtr implementation.
// DO NOT USE THESE CLASSES DIRECTLY YOURSELF.
-class WeakReference {
+class BASE_API WeakReference {
public:
- class Flag : public RefCounted<Flag>, public base::NonThreadSafe {
+ // While Flag is bound to a specific thread, it may be deleted from another
+ // via base::WeakPtr::~WeakPtr().
+ class Flag : public RefCountedThreadSafe<Flag> {
public:
- Flag(Flag** handle);
- ~Flag();
+ explicit Flag(Flag** handle);
- void AddRef() const;
- void Release() const;
- void Invalidate() { handle_ = NULL; }
- bool is_valid() const { return handle_ != NULL; }
+ void Invalidate();
+ bool IsValid() const;
- void DetachFromThread() { base::NonThreadSafe::DetachFromThread(); }
+ void DetachFromThread() { thread_checker_.DetachFromThread(); }
private:
+ friend class base::RefCountedThreadSafe<Flag>;
+
+ ~Flag();
+
+ ThreadChecker thread_checker_;
Flag** handle_;
};
@@ -90,7 +95,7 @@ class WeakReference {
scoped_refptr<Flag> flag_;
};
-class WeakReferenceOwner {
+class BASE_API WeakReferenceOwner {
public:
WeakReferenceOwner();
~WeakReferenceOwner();
@@ -116,7 +121,7 @@ class WeakReferenceOwner {
// constructor by avoiding the need for a public accessor for ref_. A
// WeakPtr<T> cannot access the private members of WeakPtr<U>, so this
// base class gives us a way to access ref_ in a protected fashion.
-class WeakPtrBase {
+class BASE_API WeakPtrBase {
public:
WeakPtrBase();
~WeakPtrBase();
@@ -234,6 +239,11 @@ class WeakPtrFactory {
return weak_reference_owner_.HasRefs();
}
+ // Indicates that this object will be used on another thread from now on.
+ void DetachFromThread() {
+ weak_reference_owner_.DetachFromThread();
+ }
+
private:
internal::WeakReferenceOwner weak_reference_owner_;
T* ptr_;
@@ -242,4 +252,4 @@ class WeakPtrFactory {
} // namespace base
-#endif // BASE_WEAK_PTR_H_
+#endif // BASE_MEMORY_WEAK_PTR_H_
diff --git a/base/weak_ptr_unittest.cc b/base/memory/weak_ptr_unittest.cc
index bcaca9e..6c2a7e8 100644
--- a/base/weak_ptr_unittest.cc
+++ b/base/memory/weak_ptr_unittest.cc
@@ -1,12 +1,12 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "base/message_loop.h"
#include "base/threading/thread.h"
-#include "base/scoped_ptr.h"
-#include "base/weak_ptr.h"
namespace base {
namespace {
diff --git a/base/message_loop.cc b/base/message_loop.cc
index f726dfc..f23caa0 100644
--- a/base/message_loop.cc
+++ b/base/message_loop.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -122,7 +122,11 @@ MessageLoop::MessageLoop(Type type)
: type_(type),
nestable_tasks_allowed_(true),
exception_restoration_(false),
+ message_histogram_(NULL),
state_(NULL),
+#ifdef OS_WIN
+ os_modal_loop_(false),
+#endif // OS_WIN
next_sequence_num_(0) {
DCHECK(!current()) << "should only have one message loop per thread";
lazy_tls_ptr.Pointer()->Set(this);
@@ -533,7 +537,7 @@ void MessageLoop::PostTask_Helper(
// on each thread.
void MessageLoop::StartHistogrammer() {
- if (enable_histogrammer_ && !message_histogram_.get()
+ if (enable_histogrammer_ && !message_histogram_
&& base::StatisticsRecorder::IsActive()) {
DCHECK(!thread_name_.empty());
message_histogram_ = base::LinearHistogram::FactoryGet(
@@ -546,7 +550,7 @@ void MessageLoop::StartHistogrammer() {
}
void MessageLoop::HistogramEvent(int event) {
- if (message_histogram_.get())
+ if (message_histogram_)
message_histogram_->Add(event);
}
diff --git a/base/message_loop.h b/base/message_loop.h
index c1dce43..519e4a3 100644
--- a/base/message_loop.h
+++ b/base/message_loop.h
@@ -9,10 +9,11 @@
#include <queue>
#include <string>
+#include "base/base_api.h"
#include "base/basictypes.h"
+#include "base/memory/ref_counted.h"
#include "base/message_pump.h"
#include "base/observer_list.h"
-#include "base/ref_counted.h"
#include "base/synchronization/lock.h"
#include "base/task.h"
@@ -65,7 +66,7 @@ class Histogram;
// Please be SURE your task is reentrant (nestable) and all global variables
// are stable and accessible before calling SetNestableTasksAllowed(true).
//
-class MessageLoop : public base::MessagePump::Delegate {
+class BASE_API MessageLoop : public base::MessagePump::Delegate {
public:
#if defined(OS_WIN)
typedef base::MessagePumpWin::Dispatcher Dispatcher;
@@ -117,7 +118,7 @@ class MessageLoop : public base::MessagePump::Delegate {
// NOTE: Any tasks posted to the MessageLoop during this notification will
// not be run. Instead, they will be deleted.
//
- class DestructionObserver {
+ class BASE_API DestructionObserver {
public:
virtual void WillDestroyCurrentMessageLoop() = 0;
@@ -283,7 +284,7 @@ class MessageLoop : public base::MessagePump::Delegate {
// MessageLoop.
//
// NOTE: A TaskObserver implementation should be extremely fast!
- class TaskObserver {
+ class BASE_API TaskObserver {
public:
TaskObserver();
@@ -319,6 +320,16 @@ class MessageLoop : public base::MessagePump::Delegate {
// Asserts that the MessageLoop is "idle".
void AssertIdle() const;
+#if defined(OS_WIN)
+ void set_os_modal_loop(bool os_modal_loop) {
+ os_modal_loop_ = os_modal_loop;
+ }
+
+ bool os_modal_loop() const {
+ return os_modal_loop_;
+ }
+#endif // OS_WIN
+
//----------------------------------------------------------------------------
protected:
struct RunState {
@@ -462,7 +473,7 @@ class MessageLoop : public base::MessagePump::Delegate {
std::string thread_name_;
// A profiling histogram showing the counts of various messages and events.
- scoped_refptr<base::Histogram> message_histogram_;
+ base::Histogram* message_histogram_;
// A null terminated list which creates an incoming_queue of tasks that are
// acquired under a mutex for processing on this instance's thread. These
@@ -476,6 +487,9 @@ class MessageLoop : public base::MessagePump::Delegate {
#if defined(OS_WIN)
base::TimeTicks high_resolution_timer_expiration_;
+ // Should be set to true before calling Windows APIs like TrackPopupMenu, etc
+ // which enter a modal message loop.
+ bool os_modal_loop_;
#endif
// The next sequence number to use for delayed tasks.
@@ -483,6 +497,7 @@ class MessageLoop : public base::MessagePump::Delegate {
ObserverList<TaskObserver> task_observers_;
+ private:
DISALLOW_COPY_AND_ASSIGN(MessageLoop);
};
@@ -493,7 +508,7 @@ class MessageLoop : public base::MessagePump::Delegate {
// This class is typically used like so:
// MessageLoopForUI::current()->...call some method...
//
-class MessageLoopForUI : public MessageLoop {
+class BASE_API MessageLoopForUI : public MessageLoop {
public:
MessageLoopForUI() : MessageLoop(TYPE_UI) {
}
@@ -549,7 +564,7 @@ COMPILE_ASSERT(sizeof(MessageLoop) == sizeof(MessageLoopForUI),
// This class is typically used like so:
// MessageLoopForIO::current()->...call some method...
//
-class MessageLoopForIO : public MessageLoop {
+class BASE_API MessageLoopForIO : public MessageLoop {
public:
#if defined(OS_WIN)
typedef base::MessagePumpForIO::IOHandler IOHandler;
diff --git a/base/message_loop_proxy.h b/base/message_loop_proxy.h
index 6a8cbe8..07bca64 100644
--- a/base/message_loop_proxy.h
+++ b/base/message_loop_proxy.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -6,8 +6,9 @@
#define BASE_MESSAGE_LOOP_PROXY_H_
#pragma once
+#include "base/base_api.h"
#include "base/basictypes.h"
-#include "base/ref_counted.h"
+#include "base/memory/ref_counted.h"
#include "base/task.h"
namespace base {
@@ -18,7 +19,7 @@ struct MessageLoopProxyTraits;
// of a message loop. This class can outlive the target message loop. You can
// obtain a MessageLoopProxy via Thread::message_loop_proxy() or
// MessageLoopProxy::CreateForCurrentThread().
-class MessageLoopProxy
+class BASE_API MessageLoopProxy
: public base::RefCountedThreadSafe<MessageLoopProxy,
MessageLoopProxyTraits> {
public:
@@ -26,8 +27,10 @@ class MessageLoopProxy
// either post the Task to the MessageLoop (if it's still alive), or to
// delete the Task otherwise.
// They return true iff the thread existed and the task was posted. Note that
- // even if the task is posted, there's no guarantee that it will run, since
- // the target thread may already have a Quit message in its queue.
+ // even if the task is posted, there's no guarantee that it will run; for
+ // example the target loop may already be quitting, or in the case of a
+ // delayed task a Quit message may preempt it in the message loop queue.
+ // Conversely, a return value of false is a guarantee the task will not run.
virtual bool PostTask(const tracked_objects::Location& from_here,
Task* task) = 0;
virtual bool PostDelayedTask(const tracked_objects::Location& from_here,
@@ -58,6 +61,7 @@ class MessageLoopProxy
static scoped_refptr<MessageLoopProxy> CreateForCurrentThread();
protected:
+ friend class RefCountedThreadSafe<MessageLoopProxy, MessageLoopProxyTraits>;
friend struct MessageLoopProxyTraits;
MessageLoopProxy();
diff --git a/base/message_loop_proxy_impl.h b/base/message_loop_proxy_impl.h
index 03e0271..80d9a26 100644
--- a/base/message_loop_proxy_impl.h
+++ b/base/message_loop_proxy_impl.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -6,6 +6,7 @@
#define BASE_MESSAGE_LOOP_PROXY_IMPL_H_
#pragma once
+#include "base/base_api.h"
#include "base/message_loop.h"
#include "base/message_loop_proxy.h"
#include "base/synchronization/lock.h"
@@ -15,8 +16,8 @@ namespace base {
// A stock implementation of MessageLoopProxy that takes in a MessageLoop
// and keeps track of its lifetime using the MessageLoop DestructionObserver.
// For now a MessageLoopProxyImpl can only be created for the current thread.
-class MessageLoopProxyImpl : public MessageLoopProxy,
- public MessageLoop::DestructionObserver {
+class BASE_API MessageLoopProxyImpl : public MessageLoopProxy,
+ public MessageLoop::DestructionObserver {
public:
virtual ~MessageLoopProxyImpl();
diff --git a/base/message_loop_proxy_impl_unittest.cc b/base/message_loop_proxy_impl_unittest.cc
index 61c7850..558cd93 100644
--- a/base/message_loop_proxy_impl_unittest.cc
+++ b/base/message_loop_proxy_impl_unittest.cc
@@ -1,10 +1,10 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
+#include "base/memory/scoped_ptr.h"
#include "base/message_loop.h"
#include "base/message_loop_proxy_impl.h"
-#include "base/scoped_ptr.h"
#include "base/threading/thread.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/platform_test.h"
diff --git a/base/message_loop_unittest.cc b/base/message_loop_unittest.cc
index 2869bb8..cd681f3 100644
--- a/base/message_loop_unittest.cc
+++ b/base/message_loop_unittest.cc
@@ -6,8 +6,8 @@
#include "base/eintr_wrapper.h"
#include "base/logging.h"
+#include "base/memory/ref_counted.h"
#include "base/message_loop.h"
-#include "base/ref_counted.h"
#include "base/task.h"
#include "base/threading/platform_thread.h"
#include "base/threading/thread.h"
diff --git a/base/message_pump.h b/base/message_pump.h
index 866b33a..6a48e81 100644
--- a/base/message_pump.h
+++ b/base/message_pump.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -6,17 +6,18 @@
#define BASE_MESSAGE_PUMP_H_
#pragma once
-#include "base/ref_counted.h"
+#include "base/base_api.h"
+#include "base/memory/ref_counted.h"
namespace base {
class TimeTicks;
-class MessagePump : public RefCountedThreadSafe<MessagePump> {
+class BASE_API MessagePump : public RefCountedThreadSafe<MessagePump> {
public:
// Please see the comments above the Run method for an illustration of how
// these delegate methods are used.
- class Delegate {
+ class BASE_API Delegate {
public:
virtual ~Delegate() {}
diff --git a/base/message_pump_glib.h b/base/message_pump_glib.h
index 70bf108..7d7d8da 100644
--- a/base/message_pump_glib.h
+++ b/base/message_pump_glib.h
@@ -6,9 +6,9 @@
#define BASE_MESSAGE_PUMP_GLIB_H_
#pragma once
+#include "base/memory/scoped_ptr.h"
#include "base/message_pump.h"
#include "base/observer_list.h"
-#include "base/scoped_ptr.h"
#include "base/time.h"
typedef union _GdkEvent GdkEvent;
diff --git a/base/message_pump_glib_unittest.cc b/base/message_pump_glib_unittest.cc
index fc604b9..496fda6 100644
--- a/base/message_pump_glib_unittest.cc
+++ b/base/message_pump_glib_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -10,8 +10,8 @@
#include <algorithm>
#include <vector>
+#include "base/memory/ref_counted.h"
#include "base/message_loop.h"
-#include "base/ref_counted.h"
#include "base/threading/thread.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/base/message_pump_glib_x.cc b/base/message_pump_glib_x.cc
index 06a156e..34313e5 100644
--- a/base/message_pump_glib_x.cc
+++ b/base/message_pump_glib_x.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -79,8 +79,7 @@ namespace base {
MessagePumpGlibX::MessagePumpGlibX() : base::MessagePumpForUI(),
#if defined(HAVE_XINPUT2)
xiopcode_(-1),
- masters_(),
- slaves_(),
+ pointer_devices_(),
#endif
gdksource_(NULL),
dispatching_event_(false),
@@ -112,22 +111,17 @@ void MessagePumpGlibX::SetupXInput2ForXWindow(Window xwindow) {
XISetMask(mask, XI_ButtonRelease);
XISetMask(mask, XI_Motion);
- // It is necessary to select only for the master devices. XInput2 provides
- // enough information to the event callback to decide which slave device
- // triggered the event, thus decide whether the 'pointer event' is a 'mouse
- // event' or a 'touch event'. So it is not necessary to select for the slave
- // devices here.
- XIEventMask evmasks[masters_.size()];
+ XIEventMask evmasks[pointer_devices_.size()];
int count = 0;
- for (std::set<int>::const_iterator iter = masters_.begin();
- iter != masters_.end();
+ for (std::set<int>::const_iterator iter = pointer_devices_.begin();
+ iter != pointer_devices_.end();
++iter, ++count) {
evmasks[count].deviceid = *iter;
evmasks[count].mask_len = sizeof(mask);
evmasks[count].mask = mask;
}
- XISelectEvents(xdisplay, xwindow, evmasks, masters_.size());
+ XISelectEvents(xdisplay, xwindow, evmasks, pointer_devices_.size());
// TODO(sad): Setup masks for keyboard events.
@@ -224,7 +218,8 @@ void MessagePumpGlibX::EventDispatcherX(GdkEvent* event, gpointer data) {
if (!pump_x->gdksource_) {
pump_x->gdksource_ = g_main_current_source();
- pump_x->gdkdispatcher_ = pump_x->gdksource_->source_funcs->dispatch;
+ if (pump_x->gdksource_)
+ pump_x->gdkdispatcher_ = pump_x->gdksource_->source_funcs->dispatch;
} else if (!pump_x->IsDispatchingEvent()) {
if (event->type != GDK_NOTHING &&
pump_x->capture_gdk_events_[event->type]) {
@@ -289,22 +284,25 @@ void MessagePumpGlibX::InitializeXInput2(void) {
SetupGtkWidgetRealizeNotifier(this);
// Instead of asking X for the list of devices all the time, let's maintain a
- // list of slave (physical) and master (virtual) pointer devices.
+ // list of pointer devices we care about.
+ // It is not necessary to select for slave devices. XInput2 provides enough
+ // information to the event callback to decide which slave device triggered
+ // the event, thus decide whether the 'pointer event' is a 'mouse event' or a
+ // 'touch event'.
+ // If the touch device has 'GrabDevice' set and 'SendCoreEvents' unset (which
+ // is possible), then the device is detected as a floating device, and a
+ // floating device is not connected to a master device. So it is necessary to
+ // also select on the floating devices.
int count = 0;
XIDeviceInfo* devices = XIQueryDevice(xdisplay, XIAllDevices, &count);
for (int i = 0; i < count; i++) {
XIDeviceInfo* devinfo = devices + i;
- if (devinfo->use == XISlavePointer) {
- slaves_.insert(devinfo->deviceid);
- } else if (devinfo->use == XIMasterPointer) {
- masters_.insert(devinfo->deviceid);
- }
- // We do not need to care about XIFloatingSlave, because the callback for
- // XI_HierarchyChanged event will take care of it.
+ if (devinfo->use == XIFloatingSlave || devinfo->use == XIMasterPointer)
+ pointer_devices_.insert(devinfo->deviceid);
}
XIFreeDeviceInfo(devices);
- // TODO(sad): Select on root for XI_HierarchyChanged so that slaves_ and
+ // TODO(sad): Select on root for XI_HierarchyChanged so that floats_ and
// masters_ can be kept up-to-date. This is a relatively rare event, so we can
// put it off for a later time.
// Note: It is not necessary to listen for XI_DeviceChanged events.
diff --git a/base/message_pump_glib_x.h b/base/message_pump_glib_x.h
index e94b797..e8e92d6 100644
--- a/base/message_pump_glib_x.h
+++ b/base/message_pump_glib_x.h
@@ -48,13 +48,10 @@ class MessagePumpGlibX : public MessagePumpForUI {
// The opcode used for checking events.
int xiopcode_;
- // The list of master pointer devices. We maintain this list so that it is not
- // necessary to query X for the list of devices for each GdkWindow created.
- std::set<int> masters_;
-
- // The list of slave (physical) pointer devices.
- // TODO(sad): This is currently unused, and may be removed eventually.
- std::set<int> slaves_;
+ // The list of pointer devices we care about. We maintain this list so that
+ // it is not necessary to query X for the list of devices for each
+ // GdkWindow created.
+ std::set<int> pointer_devices_;
#endif
// The event source for GDK events.
diff --git a/base/message_pump_libevent.cc b/base/message_pump_libevent.cc
index 28b4bfe..5154233 100644
--- a/base/message_pump_libevent.cc
+++ b/base/message_pump_libevent.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -11,8 +11,8 @@
#include "base/eintr_wrapper.h"
#include "base/logging.h"
#include "base/mac/scoped_nsautorelease_pool.h"
+#include "base/memory/scoped_ptr.h"
#include "base/observer_list.h"
-#include "base/scoped_ptr.h"
#include "base/time.h"
#if defined(USE_SYSTEM_LIBEVENT)
#include <event.h>
diff --git a/base/message_pump_mac.h b/base/message_pump_mac.h
index b903a1a..08d6b83 100644
--- a/base/message_pump_mac.h
+++ b/base/message_pump_mac.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -34,7 +34,6 @@
#include "base/message_pump.h"
#include <CoreFoundation/CoreFoundation.h>
-#include <IOKit/IOKitLib.h>
#if !defined(__OBJC__)
class NSAutoreleasePool;
@@ -142,12 +141,6 @@ class MessagePumpCFRunLoopBase : public MessagePump {
// the basis of run loops starting and stopping.
virtual void EnterExitRunLoop(CFRunLoopActivity activity);
- // IOKit power state change notification callback, called when the system
- // enters and leaves the sleep state.
- static void PowerStateNotification(void* info, io_service_t service,
- uint32_t message_type,
- void* message_argument);
-
// The thread's run loop.
CFRunLoopRef run_loop_;
@@ -161,11 +154,6 @@ class MessagePumpCFRunLoopBase : public MessagePump {
CFRunLoopObserverRef pre_source_observer_;
CFRunLoopObserverRef enter_exit_observer_;
- // Objects used for power state notification. See PowerStateNotification.
- io_connect_t root_power_domain_;
- IONotificationPortRef power_notification_port_;
- io_object_t power_notification_object_;
-
// (weak) Delegate passed as an argument to the innermost Run call.
Delegate* delegate_;
diff --git a/base/message_pump_mac.mm b/base/message_pump_mac.mm
index 8feb56f..2a50b64 100644
--- a/base/message_pump_mac.mm
+++ b/base/message_pump_mac.mm
@@ -1,4 +1,4 @@
-// Copyright (c) 2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -6,8 +6,6 @@
#import <AppKit/AppKit.h>
#import <Foundation/Foundation.h>
-#include <IOKit/IOMessage.h>
-#include <IOKit/pwr_mgt/IOPMLib.h>
#include <limits>
@@ -116,33 +114,12 @@ MessagePumpCFRunLoopBase::MessagePumpCFRunLoopBase()
EnterExitObserver,
&observer_context);
CFRunLoopAddObserver(run_loop_, enter_exit_observer_, kCFRunLoopCommonModes);
-
- root_power_domain_ = IORegisterForSystemPower(this,
- &power_notification_port_,
- PowerStateNotification,
- &power_notification_object_);
- if (root_power_domain_ != MACH_PORT_NULL) {
- CFRunLoopAddSource(
- run_loop_,
- IONotificationPortGetRunLoopSource(power_notification_port_),
- kCFRunLoopCommonModes);
- }
}
// Ideally called on the run loop thread. If other run loops were running
// lower on the run loop thread's stack when this object was created, the
// same number of run loops must be running when this object is destroyed.
MessagePumpCFRunLoopBase::~MessagePumpCFRunLoopBase() {
- if (root_power_domain_ != MACH_PORT_NULL) {
- CFRunLoopRemoveSource(
- run_loop_,
- IONotificationPortGetRunLoopSource(power_notification_port_),
- kCFRunLoopCommonModes);
- IODeregisterForSystemPower(&power_notification_object_);
- IOServiceClose(root_power_domain_);
- IONotificationPortDestroy(power_notification_port_);
- }
-
CFRunLoopRemoveObserver(run_loop_, enter_exit_observer_,
kCFRunLoopCommonModes);
CFRelease(enter_exit_observer_);
@@ -465,73 +442,6 @@ void MessagePumpCFRunLoopBase::EnterExitObserver(CFRunLoopObserverRef observer,
self->EnterExitRunLoop(activity);
}
-// Called from the run loop.
-// static
-void MessagePumpCFRunLoopBase::PowerStateNotification(void* info,
- io_service_t service,
- uint32_t message_type,
- void* message_argument) {
- // CFRunLoopTimer (NSTimer) is scheduled in terms of CFAbsoluteTime, which
- // measures the number of seconds since 2001-01-01 00:00:00.0 Z. It is
- // implemented in terms of kernel ticks, as in mach_absolute_time. While an
- // offset and scale factor can be applied to convert between the two time
- // bases at any time after boot, the kernel clock stops while the system is
- // asleep, altering the offset. (The offset will also change when the
- // real-time clock is adjusted.) CFRunLoopTimers are not readjusted to take
- // this into account when the system wakes up, so any timers that were
- // pending while the system was asleep will be delayed by the sleep
- // duration.
- //
- // The MessagePump interface assumes that scheduled delayed work will be
- // performed at the time ScheduleDelayedWork was asked to perform it. The
- // delay caused by the CFRunLoopTimer not firing at the appropriate time
- // results in a stall of queued delayed work when the system wakes up.
- // With this limitation, scheduled work would not be performed until
- // (system wake time + scheduled work time - system sleep time), while it
- // would be expected to be performed at (scheduled work time).
- //
- // To work around this problem, when the system wakes up from sleep, if a
- // delayed work timer is pending, it is rescheduled to fire at the original
- // time that it was scheduled to fire.
- //
- // This mechanism is not resilient if the real-time clock does not maintain
- // stable time while the system is sleeping, but it matches the behavior of
- // the various other MessagePump implementations, and MessageLoop seems to
- // be limited in the same way.
- //
- // References
- // - Chris Kane, "NSTimer and deep sleep," cocoa-dev@lists.apple.com,
- // http://lists.apple.com/archives/Cocoa-dev/2002/May/msg01547.html
- // - Apple Technical Q&A QA1340, "Registering and unregistering for sleep
- // and wake notifications,"
- // http://developer.apple.com/mac/library/qa/qa2004/qa1340.html
- // - Core Foundation source code, CF-550/CFRunLoop.c and CF-550/CFDate.c,
- // http://www.opensource.apple.com/
-
- MessagePumpCFRunLoopBase* self = static_cast<MessagePumpCFRunLoopBase*>(info);
-
- switch (message_type) {
- case kIOMessageSystemWillPowerOn:
- if (self->delayed_work_fire_time_ != kCFTimeIntervalMax) {
- CFRunLoopTimerSetNextFireDate(self->delayed_work_timer_,
- self->delayed_work_fire_time_);
- }
- break;
-
- case kIOMessageSystemWillSleep:
- case kIOMessageCanSystemSleep:
- // The system will wait for 30 seconds before entering sleep if neither
- // IOAllowPowerChange nor IOCancelPowerChange are called. That would be
- // pretty antisocial.
- IOAllowPowerChange(self->root_power_domain_,
- reinterpret_cast<long>(message_argument));
- break;
-
- default:
- break;
- }
-}
-
// Called by MessagePumpCFRunLoopBase::EnterExitRunLoop. The default
// implementation is a no-op.
void MessagePumpCFRunLoopBase::EnterExitRunLoop(CFRunLoopActivity activity) {
diff --git a/base/message_pump_win.cc b/base/message_pump_win.cc
index 6098a4a..9d0ec53 100644
--- a/base/message_pump_win.cc
+++ b/base/message_pump_win.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -6,7 +6,9 @@
#include <math.h>
+#include "base/message_loop.h"
#include "base/metrics/histogram.h"
+#include "base/win/wrapped_window_proc.h"
namespace base {
@@ -121,7 +123,7 @@ void MessagePumpForUI::ScheduleDelayedWork(const TimeTicks& delayed_work_time) {
delayed_work_time_ = delayed_work_time;
int delay_msec = GetCurrentDelay();
- DCHECK(delay_msec >= 0);
+ DCHECK_GE(delay_msec, 0);
if (delay_msec < USER_TIMER_MINIMUM)
delay_msec = USER_TIMER_MINIMUM;
@@ -232,7 +234,7 @@ void MessagePumpForUI::InitMessageWnd() {
WNDCLASSEX wc = {0};
wc.cbSize = sizeof(wc);
- wc.lpfnWndProc = WndProcThunk;
+ wc.lpfnWndProc = base::win::WrappedWindowProc<WndProcThunk>;
wc.hInstance = hinst;
wc.lpszClassName = kWndClass;
RegisterClassEx(&wc);
@@ -370,8 +372,19 @@ bool MessagePumpForUI::ProcessPumpReplacementMessage() {
// possibly be posted), and finally dispatches that peeked replacement. Note
// that the re-post of kMsgHaveWork may be asynchronous to this thread!!
+ bool have_message = false;
MSG msg;
- bool have_message = (0 != PeekMessage(&msg, NULL, 0, 0, PM_REMOVE));
+ // We should not process all window messages if we are in the context of an
+ // OS modal loop, i.e. in the context of a windows API call like MessageBox.
+ // This is to ensure that these messages are peeked out by the OS modal loop.
+ if (MessageLoop::current()->os_modal_loop()) {
+ // We only peek out WM_PAINT and WM_TIMER here for reasons mentioned above.
+ have_message = PeekMessage(&msg, NULL, WM_PAINT, WM_PAINT, PM_REMOVE) ||
+ PeekMessage(&msg, NULL, WM_TIMER, WM_TIMER, PM_REMOVE);
+ } else {
+ have_message = (0 != PeekMessage(&msg, NULL, 0, 0, PM_REMOVE));
+ }
+
DCHECK(!have_message || kMsgHaveWork != msg.message ||
msg.hwnd != message_hwnd_);
diff --git a/base/message_pump_win.h b/base/message_pump_win.h
index af97530..5642220 100644
--- a/base/message_pump_win.h
+++ b/base/message_pump_win.h
@@ -10,6 +10,7 @@
#include <list>
+#include "base/base_api.h"
#include "base/basictypes.h"
#include "base/message_pump.h"
#include "base/observer_list.h"
@@ -21,7 +22,7 @@ namespace base {
// MessagePumpWin serves as the base for specialized versions of the MessagePump
// for Windows. It provides basic functionality like handling of observers and
// controlling the lifetime of the message pump.
-class MessagePumpWin : public MessagePump {
+class BASE_API MessagePumpWin : public MessagePump {
public:
// An Observer is an object that receives global notifications from the
// UI MessageLoop.
@@ -156,7 +157,7 @@ class MessagePumpWin : public MessagePump {
// an excellent choice. It is also helpful that the starter messages that are
// placed in the queue when new task arrive also awakens DoRunLoop.
//
-class MessagePumpForUI : public MessagePumpWin {
+class BASE_API MessagePumpForUI : public MessagePumpWin {
public:
// The application-defined code passed to the hook procedure.
static const int kMessageFilterCode = 0x5001;
@@ -195,7 +196,7 @@ class MessagePumpForUI : public MessagePumpWin {
// deal with Windows mesagges, and instead has a Run loop based on Completion
// Ports so it is better suited for IO operations.
//
-class MessagePumpForIO : public MessagePumpWin {
+class BASE_API MessagePumpForIO : public MessagePumpWin {
public:
struct IOContext;
diff --git a/base/metrics/field_trial.h b/base/metrics/field_trial.h
index 8b4a606..dcfd391 100644
--- a/base/metrics/field_trial.h
+++ b/base/metrics/field_trial.h
@@ -30,32 +30,44 @@
// Somewhere in main thread initialization code, we'd probably define an
// instance of a FieldTrial, with code such as:
-// // Note, FieldTrials are reference counted, and persist automagically until
+// // FieldTrials are reference counted, and persist automagically until
// // process teardown, courtesy of their automatic registration in
// // FieldTrialList.
-// scoped_refptr<FieldTrial> trial = new FieldTrial("MemoryExperiment", 1000);
-// int group1 = trial->AppendGroup("high_mem", 20); // 2% in high_mem group.
-// int group2 = trial->AppendGroup("low_mem", 20); // 2% in low_mem group.
+// // Note: This field trial will run in Chrome instances compiled through
+// // 8 July, 2015, and after that all instances will be in "StandardMem".
+// scoped_refptr<FieldTrial> trial = new FieldTrial("MemoryExperiment", 1000,
+// "StandardMem", 2015, 7, 8);
+// const int kHighMemGroup =
+// trial->AppendGroup("HighMem", 20); // 2% in HighMem group.
+// const int kLowMemGroup =
+// trial->AppendGroup("LowMem", 20); // 2% in LowMem group.
// // Take action depending of which group we randomly land in.
-// if (trial->group() == group1)
+// if (trial->group() == kHighMemGroup)
// SetPruningAlgorithm(kType1); // Sample setting of browser state.
-// else if (trial->group() == group2)
+// else if (trial->group() == kLowMemGroup)
// SetPruningAlgorithm(kType2); // Sample alternate setting.
-// We then modify any histograms we wish to correlate with our experiment to
-// have slighly different names, depending on what group the trial instance
-// happened (randomly) to be assigned to:
+// We then, in addition to our original histogram, output histograms which have
+// slightly different names depending on what group the trial instance happened
+// to randomly be assigned:
-// HISTOGRAM_COUNTS(FieldTrial::MakeName("Memory.RendererTotal",
-// "MemoryExperiment").data(), count);
+// HISTOGRAM_COUNTS("Memory.RendererTotal", count); // The original histogram.
+// static bool use_memoryexperiment_histogram(
+// base::FieldTrialList::Find("MemoryExperiment") &&
+// !base::FieldTrialList::Find("MemoryExperiment")->group_name().empty());
+// if (use_memoryexperiment_histogram) {
+// HISTOGRAM_COUNTS(FieldTrial::MakeName("Memory.RendererTotal",
+// "MemoryExperiment"), count);
+// }
-// The above code will create 3 distinct histograms, with each run of the
+// The above code will create four distinct histograms, with each run of the
// application being assigned to of of the three groups, and for each group, the
// correspondingly named histogram will be populated:
-// Memory.RendererTotal // 96% of users still fill this histogram.
-// Memory.RendererTotal_high_mem // 2% of users will fill this histogram.
-// Memory.RendererTotal_low_mem // 2% of users will fill this histogram.
+// Memory.RendererTotal // 100% of users still fill this histogram.
+// Memory.RendererTotal_HighMem // 2% of users will fill this histogram.
+// Memory.RendererTotal_LowMem // 2% of users will fill this histogram.
+// Memory.RendererTotal_StandardMem // 96% of users will fill this histogram.
//------------------------------------------------------------------------------
@@ -66,8 +78,9 @@
#include <map>
#include <string>
+#include "base/base_api.h"
#include "base/gtest_prod_util.h"
-#include "base/ref_counted.h"
+#include "base/memory/ref_counted.h"
#include "base/synchronization/lock.h"
#include "base/time.h"
@@ -75,7 +88,7 @@ namespace base {
class FieldTrialList;
-class FieldTrial : public RefCounted<FieldTrial> {
+class BASE_API FieldTrial : public RefCounted<FieldTrial> {
public:
typedef int Probability; // Probability type for being selected in a trial.
@@ -198,7 +211,7 @@ class FieldTrial : public RefCounted<FieldTrial> {
// Class with a list of all active field trials. A trial is active if it has
// been registered, which includes evaluating its state based on its probaility.
// Only one instance of this class exists.
-class FieldTrialList {
+class BASE_API FieldTrialList {
public:
// Define a separator charactor to use when creating a persistent form of an
// instance. This is intended for use as a command line argument, passed to a
diff --git a/base/metrics/histogram.cc b/base/metrics/histogram.cc
index 1d6f884..4262853 100644
--- a/base/metrics/histogram.cc
+++ b/base/metrics/histogram.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -73,9 +73,12 @@ typedef Histogram::Count Count;
// static
const size_t Histogram::kBucketCount_MAX = 16384u;
-scoped_refptr<Histogram> Histogram::FactoryGet(const std::string& name,
- Sample minimum, Sample maximum, size_t bucket_count, Flags flags) {
- scoped_refptr<Histogram> histogram(NULL);
+Histogram* Histogram::FactoryGet(const std::string& name,
+ Sample minimum,
+ Sample maximum,
+ size_t bucket_count,
+ Flags flags) {
+ Histogram* histogram(NULL);
// Defensive code.
if (minimum < 1)
@@ -84,22 +87,28 @@ scoped_refptr<Histogram> Histogram::FactoryGet(const std::string& name,
maximum = kSampleType_MAX - 1;
if (!StatisticsRecorder::FindHistogram(name, &histogram)) {
- histogram = new Histogram(name, minimum, maximum, bucket_count);
- histogram->InitializeBucketRange();
- StatisticsRecorder::RegisterOrDiscardDuplicate(&histogram);
+ // Extra variable is not needed... but this keeps this section basically
+ // identical to other derived classes in this file (and compiler will
+ // optimize away the extra variable.
+ // To avoid racy destruction at shutdown, the following will be leaked.
+ Histogram* tentative_histogram =
+ new Histogram(name, minimum, maximum, bucket_count);
+ tentative_histogram->InitializeBucketRange();
+ tentative_histogram->SetFlags(flags);
+ histogram =
+ StatisticsRecorder::RegisterOrDeleteDuplicate(tentative_histogram);
}
DCHECK_EQ(HISTOGRAM, histogram->histogram_type());
DCHECK(histogram->HasConstructorArguments(minimum, maximum, bucket_count));
- histogram->SetFlags(flags);
return histogram;
}
-scoped_refptr<Histogram> Histogram::FactoryTimeGet(const std::string& name,
- TimeDelta minimum,
- TimeDelta maximum,
- size_t bucket_count,
- Flags flags) {
+Histogram* Histogram::FactoryTimeGet(const std::string& name,
+ TimeDelta minimum,
+ TimeDelta maximum,
+ size_t bucket_count,
+ Flags flags) {
return FactoryGet(name, minimum.InMilliseconds(), maximum.InMilliseconds(),
bucket_count, flags);
}
@@ -259,7 +268,7 @@ bool Histogram::DeserializeHistogramInfo(const std::string& histogram_info) {
DCHECK_NE(NOT_VALID_IN_RENDERER, histogram_type);
- scoped_refptr<Histogram> render_histogram(NULL);
+ Histogram* render_histogram(NULL);
if (histogram_type == HISTOGRAM) {
render_histogram = Histogram::FactoryGet(
@@ -610,13 +619,8 @@ void Histogram::WriteAsciiHeader(const SampleSet& snapshot,
DCHECK_EQ(snapshot.sum(), 0);
} else {
double average = static_cast<float>(snapshot.sum()) / sample_count;
- double variance = static_cast<float>(snapshot.square_sum())/sample_count
- - average * average;
- double standard_deviation = sqrt(variance);
- StringAppendF(output,
- ", average = %.1f, standard deviation = %.1f",
- average, standard_deviation);
+ StringAppendF(output, ", average = %.1f", average);
}
if (flags_ & ~kHexRangePrintingFlag)
StringAppendF(output, " (flags = 0x%x)", flags_ & ~kHexRangePrintingFlag);
@@ -661,7 +665,6 @@ void Histogram::WriteAsciiBucketGraph(double current_size, double max_size,
Histogram::SampleSet::SampleSet()
: counts_(),
sum_(0),
- square_sum_(0),
redundant_count_(0) {
}
@@ -682,11 +685,9 @@ void Histogram::SampleSet::Accumulate(Sample value, Count count,
DCHECK(count == 1 || count == -1);
counts_[index] += count;
sum_ += count * value;
- square_sum_ += (count * value) * static_cast<int64>(value);
redundant_count_ += count;
DCHECK_GE(counts_[index], 0);
DCHECK_GE(sum_, 0);
- DCHECK_GE(square_sum_, 0);
DCHECK_GE(redundant_count_, 0);
}
@@ -703,7 +704,6 @@ Count Histogram::SampleSet::TotalCount() const {
void Histogram::SampleSet::Add(const SampleSet& other) {
DCHECK_EQ(counts_.size(), other.counts_.size());
sum_ += other.sum_;
- square_sum_ += other.square_sum_;
redundant_count_ += other.redundant_count_;
for (size_t index = 0; index < counts_.size(); ++index)
counts_[index] += other.counts_[index];
@@ -711,11 +711,10 @@ void Histogram::SampleSet::Add(const SampleSet& other) {
void Histogram::SampleSet::Subtract(const SampleSet& other) {
DCHECK_EQ(counts_.size(), other.counts_.size());
- // Note: Race conditions in snapshotting a sum or square_sum may lead to
- // (temporary) negative values when snapshots are later combined (and deltas
- // calculated). As a result, we don't currently CHCEK() for positive values.
+ // Note: Race conditions in snapshotting a sum may lead to (temporary)
+ // negative values when snapshots are later combined (and deltas calculated).
+ // As a result, we don't currently CHCEK() for positive values.
sum_ -= other.sum_;
- square_sum_ -= other.square_sum_;
redundant_count_ -= other.redundant_count_;
for (size_t index = 0; index < counts_.size(); ++index) {
counts_[index] -= other.counts_[index];
@@ -725,7 +724,6 @@ void Histogram::SampleSet::Subtract(const SampleSet& other) {
bool Histogram::SampleSet::Serialize(Pickle* pickle) const {
pickle->WriteInt64(sum_);
- pickle->WriteInt64(square_sum_);
pickle->WriteInt64(redundant_count_);
pickle->WriteSize(counts_.size());
@@ -739,13 +737,11 @@ bool Histogram::SampleSet::Serialize(Pickle* pickle) const {
bool Histogram::SampleSet::Deserialize(void** iter, const Pickle& pickle) {
DCHECK_EQ(counts_.size(), 0u);
DCHECK_EQ(sum_, 0);
- DCHECK_EQ(square_sum_, 0);
DCHECK_EQ(redundant_count_, 0);
size_t counts_size;
if (!pickle.ReadInt64(iter, &sum_) ||
- !pickle.ReadInt64(iter, &square_sum_) ||
!pickle.ReadInt64(iter, &redundant_count_) ||
!pickle.ReadSize(iter, &counts_size)) {
return false;
@@ -774,12 +770,12 @@ bool Histogram::SampleSet::Deserialize(void** iter, const Pickle& pickle) {
LinearHistogram::~LinearHistogram() {
}
-scoped_refptr<Histogram> LinearHistogram::FactoryGet(const std::string& name,
- Sample minimum,
- Sample maximum,
- size_t bucket_count,
- Flags flags) {
- scoped_refptr<Histogram> histogram(NULL);
+Histogram* LinearHistogram::FactoryGet(const std::string& name,
+ Sample minimum,
+ Sample maximum,
+ size_t bucket_count,
+ Flags flags) {
+ Histogram* histogram(NULL);
if (minimum < 1)
minimum = 1;
@@ -787,25 +783,25 @@ scoped_refptr<Histogram> LinearHistogram::FactoryGet(const std::string& name,
maximum = kSampleType_MAX - 1;
if (!StatisticsRecorder::FindHistogram(name, &histogram)) {
- LinearHistogram* linear_histogram =
+ // To avoid racy destruction at shutdown, the following will be leaked.
+ LinearHistogram* tentative_histogram =
new LinearHistogram(name, minimum, maximum, bucket_count);
- linear_histogram->InitializeBucketRange();
- histogram = linear_histogram;
- StatisticsRecorder::RegisterOrDiscardDuplicate(&histogram);
+ tentative_histogram->InitializeBucketRange();
+ tentative_histogram->SetFlags(flags);
+ histogram =
+ StatisticsRecorder::RegisterOrDeleteDuplicate(tentative_histogram);
}
DCHECK_EQ(LINEAR_HISTOGRAM, histogram->histogram_type());
DCHECK(histogram->HasConstructorArguments(minimum, maximum, bucket_count));
- histogram->SetFlags(flags);
return histogram;
}
-scoped_refptr<Histogram> LinearHistogram::FactoryTimeGet(
- const std::string& name,
- TimeDelta minimum,
- TimeDelta maximum,
- size_t bucket_count,
- Flags flags) {
+Histogram* LinearHistogram::FactoryTimeGet(const std::string& name,
+ TimeDelta minimum,
+ TimeDelta maximum,
+ size_t bucket_count,
+ Flags flags) {
return FactoryGet(name, minimum.InMilliseconds(), maximum.InMilliseconds(),
bucket_count, flags);
}
@@ -875,19 +871,19 @@ bool LinearHistogram::PrintEmptyBucket(size_t index) const {
// This section provides implementation for BooleanHistogram.
//------------------------------------------------------------------------------
-scoped_refptr<Histogram> BooleanHistogram::FactoryGet(const std::string& name,
- Flags flags) {
- scoped_refptr<Histogram> histogram(NULL);
+Histogram* BooleanHistogram::FactoryGet(const std::string& name, Flags flags) {
+ Histogram* histogram(NULL);
if (!StatisticsRecorder::FindHistogram(name, &histogram)) {
- BooleanHistogram* boolean_histogram = new BooleanHistogram(name);
- boolean_histogram->InitializeBucketRange();
- histogram = boolean_histogram;
- StatisticsRecorder::RegisterOrDiscardDuplicate(&histogram);
+ // To avoid racy destruction at shutdown, the following will be leaked.
+ BooleanHistogram* tentative_histogram = new BooleanHistogram(name);
+ tentative_histogram->InitializeBucketRange();
+ tentative_histogram->SetFlags(flags);
+ histogram =
+ StatisticsRecorder::RegisterOrDeleteDuplicate(tentative_histogram);
}
DCHECK_EQ(BOOLEAN_HISTOGRAM, histogram->histogram_type());
- histogram->SetFlags(flags);
return histogram;
}
@@ -907,11 +903,10 @@ BooleanHistogram::BooleanHistogram(const std::string& name)
// CustomHistogram:
//------------------------------------------------------------------------------
-scoped_refptr<Histogram> CustomHistogram::FactoryGet(
- const std::string& name,
- const std::vector<Sample>& custom_ranges,
- Flags flags) {
- scoped_refptr<Histogram> histogram(NULL);
+Histogram* CustomHistogram::FactoryGet(const std::string& name,
+ const std::vector<Sample>& custom_ranges,
+ Flags flags) {
+ Histogram* histogram(NULL);
// Remove the duplicates in the custom ranges array.
std::vector<int> ranges = custom_ranges;
@@ -927,16 +922,17 @@ scoped_refptr<Histogram> CustomHistogram::FactoryGet(
DCHECK_LT(ranges.back(), kSampleType_MAX);
if (!StatisticsRecorder::FindHistogram(name, &histogram)) {
- CustomHistogram* custom_histogram = new CustomHistogram(name, ranges);
- custom_histogram->InitializedCustomBucketRange(ranges);
- histogram = custom_histogram;
- StatisticsRecorder::RegisterOrDiscardDuplicate(&histogram);
+ // To avoid racy destruction at shutdown, the following will be leaked.
+ CustomHistogram* tentative_histogram = new CustomHistogram(name, ranges);
+ tentative_histogram->InitializedCustomBucketRange(ranges);
+ tentative_histogram->SetFlags(flags);
+ histogram =
+ StatisticsRecorder::RegisterOrDeleteDuplicate(tentative_histogram);
}
DCHECK_EQ(histogram->histogram_type(), CUSTOM_HISTOGRAM);
DCHECK(histogram->HasConstructorArguments(ranges[1], ranges.back(),
ranges.size()));
- histogram->SetFlags(flags);
return histogram;
}
@@ -1017,27 +1013,23 @@ bool StatisticsRecorder::IsActive() {
return NULL != histograms_;
}
-// Note: We can't accept a ref_ptr to |histogram| because we *might* not keep a
-// reference, and we are called while in the Histogram constructor. In that
-// scenario, a ref_ptr would have incremented the ref count when the histogram
-// was passed to us, decremented it when we returned, and the instance would be
-// destroyed before assignment (when value was returned by new).
-// static
-void StatisticsRecorder::RegisterOrDiscardDuplicate(
- scoped_refptr<Histogram>* histogram) {
- DCHECK((*histogram)->HasValidRangeChecksum());
+Histogram* StatisticsRecorder::RegisterOrDeleteDuplicate(Histogram* histogram) {
+ DCHECK(histogram->HasValidRangeChecksum());
if (lock_ == NULL)
- return;
+ return histogram;
base::AutoLock auto_lock(*lock_);
if (!histograms_)
- return;
- const std::string name = (*histogram)->histogram_name();
+ return histogram;
+ const std::string name = histogram->histogram_name();
HistogramMap::iterator it = histograms_->find(name);
// Avoid overwriting a previous registration.
- if (histograms_->end() == it)
- (*histograms_)[name] = *histogram;
- else
- *histogram = it->second;
+ if (histograms_->end() == it) {
+ (*histograms_)[name] = histogram;
+ } else {
+ delete histogram; // We already have one by this name.
+ histogram = it->second;
+ }
+ return histogram;
}
// static
@@ -1100,7 +1092,7 @@ void StatisticsRecorder::GetHistograms(Histograms* output) {
}
bool StatisticsRecorder::FindHistogram(const std::string& name,
- scoped_refptr<Histogram>* histogram) {
+ Histogram** histogram) {
if (lock_ == NULL)
return false;
base::AutoLock auto_lock(*lock_);
diff --git a/base/metrics/histogram.h b/base/metrics/histogram.h
index 347932a..bc58ee5 100644
--- a/base/metrics/histogram.h
+++ b/base/metrics/histogram.h
@@ -28,6 +28,15 @@
// at the low end of the histogram scale, but allows the histogram to cover a
// gigantic range with the addition of very few buckets.
+// Histograms use a pattern involving a function static variable, that is a
+// pointer to a histogram. This static is explicitly initialized on any thread
+// that detects a uninitialized (NULL) pointer. The potentially racy
+// initialization is not a problem as it is always set to point to the same
+// value (i.e., the FactoryGet always returns the same value). FactoryGet
+// is also completely thread safe, which results in a completely thread safe,
+// and relatively fast, set of counters. To avoid races at shutdown, the static
+// pointer is NOT deleted, and we leak the histograms at process termination.
+
#ifndef BASE_METRICS_HISTOGRAM_H_
#define BASE_METRICS_HISTOGRAM_H_
#pragma once
@@ -36,8 +45,8 @@
#include <string>
#include <vector>
+#include "base/base_api.h"
#include "base/gtest_prod_util.h"
-#include "base/ref_counted.h"
#include "base/logging.h"
#include "base/time.h"
@@ -65,11 +74,12 @@ class Lock;
name, sample, 1, 10000, 50)
#define HISTOGRAM_CUSTOM_COUNTS(name, sample, min, max, bucket_count) do { \
- static scoped_refptr<base::Histogram> counter = \
- base::Histogram::FactoryGet(name, min, max, bucket_count, \
- base::Histogram::kNoFlags); \
+ static base::Histogram* counter(NULL); \
+ if (!counter) \
+ counter = base::Histogram::FactoryGet(name, min, max, bucket_count, \
+ base::Histogram::kNoFlags); \
DCHECK_EQ(name, counter->histogram_name()); \
- if (counter.get()) counter->Add(sample); \
+ counter->Add(sample); \
} while (0)
#define HISTOGRAM_PERCENTAGE(name, under_one_hundred) \
@@ -78,40 +88,43 @@ class Lock;
// For folks that need real specific times, use this to select a precise range
// of times you want plotted, and the number of buckets you want used.
#define HISTOGRAM_CUSTOM_TIMES(name, sample, min, max, bucket_count) do { \
- static scoped_refptr<base::Histogram> counter = \
- base::Histogram::FactoryTimeGet(name, min, max, bucket_count, \
- base::Histogram::kNoFlags); \
+ static base::Histogram* counter(NULL); \
+ if (!counter) \
+ counter = base::Histogram::FactoryTimeGet(name, min, max, bucket_count, \
+ base::Histogram::kNoFlags); \
DCHECK_EQ(name, counter->histogram_name()); \
- if (counter.get()) counter->AddTime(sample); \
+ counter->AddTime(sample); \
} while (0)
// DO NOT USE THIS. It is being phased out, in favor of HISTOGRAM_CUSTOM_TIMES.
#define HISTOGRAM_CLIPPED_TIMES(name, sample, min, max, bucket_count) do { \
- static scoped_refptr<base::Histogram> counter = \
- base::Histogram::FactoryTimeGet(name, min, max, bucket_count, \
- base::Histogram::kNoFlags); \
+ static base::Histogram* counter(NULL); \
+ if (!counter) \
+ counter = base::Histogram::FactoryTimeGet(name, min, max, bucket_count, \
+ base::Histogram::kNoFlags); \
DCHECK_EQ(name, counter->histogram_name()); \
- if ((sample) < (max) && counter.get()) counter->AddTime(sample); \
+ if ((sample) < (max)) counter->AddTime(sample); \
} while (0)
// Support histograming of an enumerated value. The samples should always be
// less than boundary_value.
#define HISTOGRAM_ENUMERATION(name, sample, boundary_value) do { \
- static scoped_refptr<base::Histogram> counter = \
- base::LinearHistogram::FactoryGet(name, 1, boundary_value, \
- boundary_value + 1, \
- base::Histogram::kNoFlags); \
+ static base::Histogram* counter(NULL); \
+ if (!counter) \
+ counter = base::LinearHistogram::FactoryGet(name, 1, boundary_value, \
+ boundary_value + 1, base::Histogram::kNoFlags); \
DCHECK_EQ(name, counter->histogram_name()); \
- if (counter.get()) counter->Add(sample); \
+ counter->Add(sample); \
} while (0)
#define HISTOGRAM_CUSTOM_ENUMERATION(name, sample, custom_ranges) do { \
- static scoped_refptr<base::Histogram> counter = \
- base::CustomHistogram::FactoryGet(name, custom_ranges, \
- base::Histogram::kNoFlags); \
+ static base::Histogram* counter(NULL); \
+ if (!counter) \
+ counter = base::CustomHistogram::FactoryGet(name, custom_ranges, \
+ base::Histogram::kNoFlags); \
DCHECK_EQ(name, counter->histogram_name()); \
- if (counter.get()) counter->Add(sample); \
+ counter->Add(sample); \
} while (0)
@@ -171,20 +184,22 @@ class Lock;
base::TimeDelta::FromHours(1), 50)
#define UMA_HISTOGRAM_CUSTOM_TIMES(name, sample, min, max, bucket_count) do { \
- static scoped_refptr<base::Histogram> counter = \
- base::Histogram::FactoryTimeGet(name, min, max, bucket_count, \
+ static base::Histogram* counter(NULL); \
+ if (!counter) \
+ counter = base::Histogram::FactoryTimeGet(name, min, max, bucket_count, \
base::Histogram::kUmaTargetedHistogramFlag); \
DCHECK_EQ(name, counter->histogram_name()); \
- if (counter.get()) counter->AddTime(sample); \
+ counter->AddTime(sample); \
} while (0)
// DO NOT USE THIS. It is being phased out, in favor of HISTOGRAM_CUSTOM_TIMES.
#define UMA_HISTOGRAM_CLIPPED_TIMES(name, sample, min, max, bucket_count) do { \
- static scoped_refptr<base::Histogram> counter = \
- base::Histogram::FactoryTimeGet(name, min, max, bucket_count, \
- base::Histogram::kUmaTargetedHistogramFlag); \
+ static base::Histogram* counter(NULL); \
+ if (!counter) \
+ counter = base::Histogram::FactoryTimeGet(name, min, max, bucket_count, \
+ base::Histogram::kUmaTargetedHistogramFlag); \
DCHECK_EQ(name, counter->histogram_name()); \
- if ((sample) < (max) && counter.get()) counter->AddTime(sample); \
+ if ((sample) < (max)) counter->AddTime(sample); \
} while (0)
#define UMA_HISTOGRAM_COUNTS(name, sample) UMA_HISTOGRAM_CUSTOM_COUNTS( \
@@ -197,11 +212,12 @@ class Lock;
name, sample, 1, 10000, 50)
#define UMA_HISTOGRAM_CUSTOM_COUNTS(name, sample, min, max, bucket_count) do { \
- static scoped_refptr<base::Histogram> counter = \
- base::Histogram::FactoryGet(name, min, max, bucket_count, \
- base::Histogram::kUmaTargetedHistogramFlag); \
+ static base::Histogram* counter(NULL); \
+ if (!counter) \
+ counter = base::Histogram::FactoryGet(name, min, max, bucket_count, \
+ base::Histogram::kUmaTargetedHistogramFlag); \
DCHECK_EQ(name, counter->histogram_name()); \
- if (counter.get()) counter->Add(sample); \
+ counter->Add(sample); \
} while (0)
#define UMA_HISTOGRAM_MEMORY_KB(name, sample) UMA_HISTOGRAM_CUSTOM_COUNTS( \
@@ -213,20 +229,31 @@ class Lock;
#define UMA_HISTOGRAM_PERCENTAGE(name, under_one_hundred) \
UMA_HISTOGRAM_ENUMERATION(name, under_one_hundred, 101)
+#define UMA_HISTOGRAM_BOOLEAN(name, sample) do { \
+ static base::Histogram* counter(NULL); \
+ if (!counter) \
+ counter = base::BooleanHistogram::FactoryGet(name, \
+ base::Histogram::kUmaTargetedHistogramFlag); \
+ DCHECK_EQ(name, counter->histogram_name()); \
+ counter->AddBoolean(sample); \
+ } while (0)
+
#define UMA_HISTOGRAM_ENUMERATION(name, sample, boundary_value) do { \
- static scoped_refptr<base::Histogram> counter = \
- base::LinearHistogram::FactoryGet(name, 1, boundary_value, \
- boundary_value + 1, base::Histogram::kUmaTargetedHistogramFlag); \
+ static base::Histogram* counter(NULL); \
+ if (!counter) \
+ counter = base::LinearHistogram::FactoryGet(name, 1, boundary_value, \
+ boundary_value + 1, base::Histogram::kUmaTargetedHistogramFlag); \
DCHECK_EQ(name, counter->histogram_name()); \
- if (counter.get()) counter->Add(sample); \
+ counter->Add(sample); \
} while (0)
#define UMA_HISTOGRAM_CUSTOM_ENUMERATION(name, sample, custom_ranges) do { \
- static scoped_refptr<base::Histogram> counter = \
- base::CustomHistogram::FactoryGet(name, custom_ranges, \
- base::Histogram::kUmaTargetedHistogramFlag); \
+ static base::Histogram* counter(NULL); \
+ if (!counter) \
+ counter = base::CustomHistogram::FactoryGet(name, custom_ranges, \
+ base::Histogram::kUmaTargetedHistogramFlag); \
DCHECK_EQ(name, counter->histogram_name()); \
- if (counter.get()) counter->Add(sample); \
+ counter->Add(sample); \
} while (0)
//------------------------------------------------------------------------------
@@ -236,7 +263,7 @@ class CustomHistogram;
class Histogram;
class LinearHistogram;
-class Histogram : public base::RefCountedThreadSafe<Histogram> {
+class BASE_API Histogram {
public:
typedef int Sample; // Used for samples (and ranges of samples).
typedef int Count; // Used to count samples in a bucket.
@@ -295,7 +322,7 @@ class Histogram : public base::RefCountedThreadSafe<Histogram> {
//----------------------------------------------------------------------------
// Statistic values, developed over the life of the histogram.
- class SampleSet {
+ class BASE_API SampleSet {
public:
explicit SampleSet();
~SampleSet();
@@ -311,7 +338,6 @@ class Histogram : public base::RefCountedThreadSafe<Histogram> {
Count counts(size_t i) const { return counts_[i]; }
Count TotalCount() const;
int64 sum() const { return sum_; }
- int64 square_sum() const { return square_sum_; }
int64 redundant_count() const { return redundant_count_; }
// Arithmetic manipulation of corresponding elements of the set.
@@ -329,7 +355,6 @@ class Histogram : public base::RefCountedThreadSafe<Histogram> {
// Save simple stats locally. Note that this MIGHT get done in base class
// without shared memory at some point.
int64 sum_; // sum of samples.
- int64 square_sum_; // sum of squares of samples.
private:
// Allow tests to corrupt our innards for testing purposes.
@@ -348,11 +373,16 @@ class Histogram : public base::RefCountedThreadSafe<Histogram> {
//----------------------------------------------------------------------------
// minimum should start from 1. 0 is invalid as a minimum. 0 is an implicit
// default underflow bucket.
- static scoped_refptr<Histogram> FactoryGet(const std::string& name,
- Sample minimum, Sample maximum, size_t bucket_count, Flags flags);
- static scoped_refptr<Histogram> FactoryTimeGet(const std::string& name,
- base::TimeDelta minimum, base::TimeDelta maximum, size_t bucket_count,
- Flags flags);
+ static Histogram* FactoryGet(const std::string& name,
+ Sample minimum,
+ Sample maximum,
+ size_t bucket_count,
+ Flags flags);
+ static Histogram* FactoryTimeGet(const std::string& name,
+ base::TimeDelta minimum,
+ base::TimeDelta maximum,
+ size_t bucket_count,
+ Flags flags);
void Add(int value);
@@ -427,7 +457,6 @@ class Histogram : public base::RefCountedThreadSafe<Histogram> {
bool HasValidRangeChecksum() const;
protected:
- friend class base::RefCountedThreadSafe<Histogram>;
Histogram(const std::string& name, Sample minimum,
Sample maximum, size_t bucket_count);
Histogram(const std::string& name, TimeDelta minimum,
@@ -481,6 +510,8 @@ class Histogram : public base::RefCountedThreadSafe<Histogram> {
FRIEND_TEST(HistogramTest, Crc32SampleHash);
FRIEND_TEST(HistogramTest, Crc32TableTest);
+ friend class StatisticsRecorder; // To allow it to delete duplicates.
+
// Post constructor initialization.
void Initialize();
@@ -550,17 +581,22 @@ class Histogram : public base::RefCountedThreadSafe<Histogram> {
// LinearHistogram is a more traditional histogram, with evenly spaced
// buckets.
-class LinearHistogram : public Histogram {
+class BASE_API LinearHistogram : public Histogram {
public:
virtual ~LinearHistogram();
/* minimum should start from 1. 0 is as minimum is invalid. 0 is an implicit
default underflow bucket. */
- static scoped_refptr<Histogram> FactoryGet(const std::string& name,
- Sample minimum, Sample maximum, size_t bucket_count, Flags flags);
- static scoped_refptr<Histogram> FactoryTimeGet(const std::string& name,
- TimeDelta minimum, TimeDelta maximum, size_t bucket_count,
- Flags flags);
+ static Histogram* FactoryGet(const std::string& name,
+ Sample minimum,
+ Sample maximum,
+ size_t bucket_count,
+ Flags flags);
+ static Histogram* FactoryTimeGet(const std::string& name,
+ TimeDelta minimum,
+ TimeDelta maximum,
+ size_t bucket_count,
+ Flags flags);
// Overridden from Histogram:
virtual ClassType histogram_type() const;
@@ -601,10 +637,9 @@ class LinearHistogram : public Histogram {
//------------------------------------------------------------------------------
// BooleanHistogram is a histogram for booleans.
-class BooleanHistogram : public LinearHistogram {
+class BASE_API BooleanHistogram : public LinearHistogram {
public:
- static scoped_refptr<Histogram> FactoryGet(const std::string& name,
- Flags flags);
+ static Histogram* FactoryGet(const std::string& name, Flags flags);
virtual ClassType histogram_type() const;
@@ -619,11 +654,12 @@ class BooleanHistogram : public LinearHistogram {
//------------------------------------------------------------------------------
// CustomHistogram is a histogram for a set of custom integers.
-class CustomHistogram : public Histogram {
+class BASE_API CustomHistogram : public Histogram {
public:
- static scoped_refptr<Histogram> FactoryGet(const std::string& name,
- const std::vector<Sample>& custom_ranges, Flags flags);
+ static Histogram* FactoryGet(const std::string& name,
+ const std::vector<Sample>& custom_ranges,
+ Flags flags);
// Overridden from Histogram:
virtual ClassType histogram_type() const;
@@ -644,9 +680,9 @@ class CustomHistogram : public Histogram {
// general place for histograms to register, and supports a global API for
// accessing (i.e., dumping, or graphing) the data in all the histograms.
-class StatisticsRecorder {
+class BASE_API StatisticsRecorder {
public:
- typedef std::vector<scoped_refptr<Histogram> > Histograms;
+ typedef std::vector<Histogram*> Histograms;
StatisticsRecorder();
@@ -657,9 +693,9 @@ class StatisticsRecorder {
// Register, or add a new histogram to the collection of statistics. If an
// identically named histogram is already registered, then the argument
- // |histogram| will be replaced by the previously registered value, discarding
- // the referenced argument.
- static void RegisterOrDiscardDuplicate(scoped_refptr<Histogram>* histogram);
+ // |histogram| will deleted. The returned value is always the registered
+ // histogram (either the argument, or the pre-existing registered histogram).
+ static Histogram* RegisterOrDeleteDuplicate(Histogram* histogram);
// Methods for printing histograms. Only histograms which have query as
// a substring are written to output (an empty string will process all
@@ -673,8 +709,7 @@ class StatisticsRecorder {
// Find a histogram by name. It matches the exact name. This method is thread
// safe. If a matching histogram is not found, then the |histogram| is
// not changed.
- static bool FindHistogram(const std::string& query,
- scoped_refptr<Histogram>* histogram);
+ static bool FindHistogram(const std::string& query, Histogram** histogram);
static bool dump_on_exit() { return dump_on_exit_; }
@@ -689,7 +724,7 @@ class StatisticsRecorder {
private:
// We keep all registered histograms in a map, from name to histogram.
- typedef std::map<std::string, scoped_refptr<Histogram> > HistogramMap;
+ typedef std::map<std::string, Histogram*> HistogramMap;
static HistogramMap* histograms_;
diff --git a/base/metrics/histogram_unittest.cc b/base/metrics/histogram_unittest.cc
index afa69a6..496ff63 100644
--- a/base/metrics/histogram_unittest.cc
+++ b/base/metrics/histogram_unittest.cc
@@ -1,10 +1,11 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
// Test of Histogram class
#include "base/metrics/histogram.h"
+#include "base/scoped_ptr.h"
#include "base/time.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -17,15 +18,22 @@ class HistogramTest : public testing::Test {
// Check for basic syntax and use.
TEST(HistogramTest, StartupShutdownTest) {
// Try basic construction
- scoped_refptr<Histogram> histogram = Histogram::FactoryGet(
- "TestHistogram", 1, 1000, 10, Histogram::kNoFlags);
- scoped_refptr<Histogram> histogram1 = Histogram::FactoryGet(
- "Test1Histogram", 1, 1000, 10, Histogram::kNoFlags);
-
- scoped_refptr<Histogram> linear_histogram = LinearHistogram::FactoryGet(
- "TestLinearHistogram", 1, 1000, 10, Histogram::kNoFlags);
- scoped_refptr<Histogram> linear_histogram1 = LinearHistogram::FactoryGet(
- "Test1LinearHistogram", 1, 1000, 10, Histogram::kNoFlags);
+ Histogram* histogram(Histogram::FactoryGet(
+ "TestHistogram", 1, 1000, 10, Histogram::kNoFlags));
+ EXPECT_NE(reinterpret_cast<Histogram*>(NULL), histogram);
+ Histogram* histogram1(Histogram::FactoryGet(
+ "Test1Histogram", 1, 1000, 10, Histogram::kNoFlags));
+ EXPECT_NE(reinterpret_cast<Histogram*>(NULL), histogram1);
+ EXPECT_NE(histogram, histogram1);
+
+
+ Histogram* linear_histogram(LinearHistogram::FactoryGet(
+ "TestLinearHistogram", 1, 1000, 10, Histogram::kNoFlags));
+ EXPECT_NE(reinterpret_cast<Histogram*>(NULL), linear_histogram);
+ Histogram* linear_histogram1(LinearHistogram::FactoryGet(
+ "Test1LinearHistogram", 1, 1000, 10, Histogram::kNoFlags));
+ EXPECT_NE(reinterpret_cast<Histogram*>(NULL), linear_histogram1);
+ EXPECT_NE(linear_histogram, linear_histogram1);
std::vector<int> custom_ranges;
custom_ranges.push_back(1);
@@ -33,10 +41,12 @@ TEST(HistogramTest, StartupShutdownTest) {
custom_ranges.push_back(10);
custom_ranges.push_back(20);
custom_ranges.push_back(30);
- scoped_refptr<Histogram> custom_histogram = CustomHistogram::FactoryGet(
- "TestCustomHistogram", custom_ranges, Histogram::kNoFlags);
- scoped_refptr<Histogram> custom_histogram1 = CustomHistogram::FactoryGet(
- "Test1CustomHistogram", custom_ranges, Histogram::kNoFlags);
+ Histogram* custom_histogram(CustomHistogram::FactoryGet(
+ "TestCustomHistogram", custom_ranges, Histogram::kNoFlags));
+ EXPECT_NE(reinterpret_cast<Histogram*>(NULL), custom_histogram);
+ Histogram* custom_histogram1(CustomHistogram::FactoryGet(
+ "Test1CustomHistogram", custom_ranges, Histogram::kNoFlags));
+ EXPECT_NE(reinterpret_cast<Histogram*>(NULL), custom_histogram1);
// Use standard macros (but with fixed samples)
HISTOGRAM_TIMES("Test2Histogram", TimeDelta::FromDays(1));
@@ -70,25 +80,29 @@ TEST(HistogramTest, RecordedStartupTest) {
EXPECT_EQ(0U, histograms.size());
// Try basic construction
- scoped_refptr<Histogram> histogram = Histogram::FactoryGet(
- "TestHistogram", 1, 1000, 10, Histogram::kNoFlags);
+ Histogram* histogram(Histogram::FactoryGet(
+ "TestHistogram", 1, 1000, 10, Histogram::kNoFlags));
+ EXPECT_NE(reinterpret_cast<Histogram*>(NULL), histogram);
histograms.clear();
StatisticsRecorder::GetHistograms(&histograms); // Load up lists
EXPECT_EQ(1U, histograms.size());
- scoped_refptr<Histogram> histogram1 = Histogram::FactoryGet(
- "Test1Histogram", 1, 1000, 10, Histogram::kNoFlags);
+ Histogram* histogram1(Histogram::FactoryGet(
+ "Test1Histogram", 1, 1000, 10, Histogram::kNoFlags));
+ EXPECT_NE(reinterpret_cast<Histogram*>(NULL), histogram1);
histograms.clear();
StatisticsRecorder::GetHistograms(&histograms); // Load up lists
EXPECT_EQ(2U, histograms.size());
- scoped_refptr<Histogram> linear_histogram = LinearHistogram::FactoryGet(
- "TestLinearHistogram", 1, 1000, 10, Histogram::kNoFlags);
+ Histogram* linear_histogram(LinearHistogram::FactoryGet(
+ "TestLinearHistogram", 1, 1000, 10, Histogram::kNoFlags));
+ EXPECT_NE(reinterpret_cast<Histogram*>(NULL), linear_histogram);
histograms.clear();
StatisticsRecorder::GetHistograms(&histograms); // Load up lists
EXPECT_EQ(3U, histograms.size());
- scoped_refptr<Histogram> linear_histogram1 = LinearHistogram::FactoryGet(
- "Test1LinearHistogram", 1, 1000, 10, Histogram::kNoFlags);
+ Histogram* linear_histogram1(LinearHistogram::FactoryGet(
+ "Test1LinearHistogram", 1, 1000, 10, Histogram::kNoFlags));
+ EXPECT_NE(reinterpret_cast<Histogram*>(NULL), linear_histogram1);
histograms.clear();
StatisticsRecorder::GetHistograms(&histograms); // Load up lists
EXPECT_EQ(4U, histograms.size());
@@ -99,10 +113,12 @@ TEST(HistogramTest, RecordedStartupTest) {
custom_ranges.push_back(10);
custom_ranges.push_back(20);
custom_ranges.push_back(30);
- scoped_refptr<Histogram> custom_histogram = CustomHistogram::FactoryGet(
- "TestCustomHistogram", custom_ranges, Histogram::kNoFlags);
- scoped_refptr<Histogram> custom_histogram1 = CustomHistogram::FactoryGet(
- "TestCustomHistogram", custom_ranges, Histogram::kNoFlags);
+ Histogram* custom_histogram(CustomHistogram::FactoryGet(
+ "TestCustomHistogram", custom_ranges, Histogram::kNoFlags));
+ EXPECT_NE(reinterpret_cast<Histogram*>(NULL), custom_histogram);
+ Histogram* custom_histogram1(CustomHistogram::FactoryGet(
+ "TestCustomHistogram", custom_ranges, Histogram::kNoFlags));
+ EXPECT_NE(reinterpret_cast<Histogram*>(NULL), custom_histogram1);
histograms.clear();
StatisticsRecorder::GetHistograms(&histograms); // Load up lists
@@ -138,8 +154,8 @@ TEST(HistogramTest, RangeTest) {
recorder.GetHistograms(&histograms);
EXPECT_EQ(0U, histograms.size());
- scoped_refptr<Histogram> histogram = Histogram::FactoryGet(
- "Histogram", 1, 64, 8, Histogram::kNoFlags); // As per header file.
+ Histogram* histogram(Histogram::FactoryGet(
+ "Histogram", 1, 64, 8, Histogram::kNoFlags)); // As per header file.
// Check that we got a nice exponential when there was enough rooom.
EXPECT_EQ(0, histogram->ranges(0));
int power_of_2 = 1;
@@ -149,31 +165,30 @@ TEST(HistogramTest, RangeTest) {
}
EXPECT_EQ(INT_MAX, histogram->ranges(8));
- scoped_refptr<Histogram> short_histogram = Histogram::FactoryGet(
- "Histogram Shortened", 1, 7, 8, Histogram::kNoFlags);
+ Histogram* short_histogram(Histogram::FactoryGet(
+ "Histogram Shortened", 1, 7, 8, Histogram::kNoFlags));
// Check that when the number of buckets is short, we get a linear histogram
// for lack of space to do otherwise.
for (int i = 0; i < 8; i++)
EXPECT_EQ(i, short_histogram->ranges(i));
EXPECT_EQ(INT_MAX, short_histogram->ranges(8));
- scoped_refptr<Histogram> linear_histogram = LinearHistogram::FactoryGet(
- "Linear", 1, 7, 8, Histogram::kNoFlags);
+ Histogram* linear_histogram(LinearHistogram::FactoryGet(
+ "Linear", 1, 7, 8, Histogram::kNoFlags));
// We also get a nice linear set of bucket ranges when we ask for it
for (int i = 0; i < 8; i++)
EXPECT_EQ(i, linear_histogram->ranges(i));
EXPECT_EQ(INT_MAX, linear_histogram->ranges(8));
- scoped_refptr<Histogram> linear_broad_histogram = LinearHistogram::FactoryGet(
- "Linear widened", 2, 14, 8, Histogram::kNoFlags);
+ Histogram* linear_broad_histogram(LinearHistogram::FactoryGet(
+ "Linear widened", 2, 14, 8, Histogram::kNoFlags));
// ...but when the list has more space, then the ranges naturally spread out.
for (int i = 0; i < 8; i++)
EXPECT_EQ(2 * i, linear_broad_histogram->ranges(i));
EXPECT_EQ(INT_MAX, linear_broad_histogram->ranges(8));
- scoped_refptr<Histogram> transitioning_histogram =
- Histogram::FactoryGet("LinearAndExponential", 1, 32, 15,
- Histogram::kNoFlags);
+ Histogram* transitioning_histogram(Histogram::FactoryGet(
+ "LinearAndExponential", 1, 32, 15, Histogram::kNoFlags));
// When space is a little tight, we transition from linear to exponential.
EXPECT_EQ(0, transitioning_histogram->ranges(0));
EXPECT_EQ(1, transitioning_histogram->ranges(1));
@@ -198,8 +213,8 @@ TEST(HistogramTest, RangeTest) {
custom_ranges.push_back(10);
custom_ranges.push_back(11);
custom_ranges.push_back(300);
- scoped_refptr<Histogram> test_custom_histogram = CustomHistogram::FactoryGet(
- "TestCustomRangeHistogram", custom_ranges, Histogram::kNoFlags);
+ Histogram* test_custom_histogram(CustomHistogram::FactoryGet(
+ "TestCustomRangeHistogram", custom_ranges, Histogram::kNoFlags));
EXPECT_EQ(custom_ranges[0], test_custom_histogram->ranges(0));
EXPECT_EQ(custom_ranges[1], test_custom_histogram->ranges(1));
@@ -221,8 +236,8 @@ TEST(HistogramTest, CustomRangeTest) {
custom_ranges.push_back(9);
custom_ranges.push_back(10);
custom_ranges.push_back(11);
- scoped_refptr<Histogram> test_custom_histogram = CustomHistogram::FactoryGet(
- "TestCustomRangeHistogram", custom_ranges, Histogram::kNoFlags);
+ Histogram* test_custom_histogram(CustomHistogram::FactoryGet(
+ "TestCustomRangeHistogram", custom_ranges, Histogram::kNoFlags));
EXPECT_EQ(0, test_custom_histogram->ranges(0)); // Auto added
EXPECT_EQ(custom_ranges[0], test_custom_histogram->ranges(1));
@@ -242,8 +257,8 @@ TEST(HistogramTest, CustomRangeTest) {
custom_ranges.push_back(0); // Push an explicit zero.
custom_ranges.push_back(kBig);
- scoped_refptr<Histogram> unsorted_histogram = CustomHistogram::FactoryGet(
- "TestCustomUnsortedDupedHistogram", custom_ranges, Histogram::kNoFlags);
+ Histogram* unsorted_histogram(CustomHistogram::FactoryGet(
+ "TestCustomUnsortedDupedHistogram", custom_ranges, Histogram::kNoFlags));
EXPECT_EQ(0, unsorted_histogram->ranges(0));
EXPECT_EQ(kSmall, unsorted_histogram->ranges(1));
EXPECT_EQ(kMid, unsorted_histogram->ranges(2));
@@ -254,8 +269,8 @@ TEST(HistogramTest, CustomRangeTest) {
// Make sure histogram handles out-of-bounds data gracefully.
TEST(HistogramTest, BoundsTest) {
const size_t kBucketCount = 50;
- scoped_refptr<Histogram> histogram = Histogram::FactoryGet(
- "Bounded", 10, 100, kBucketCount, Histogram::kNoFlags);
+ Histogram* histogram(Histogram::FactoryGet(
+ "Bounded", 10, 100, kBucketCount, Histogram::kNoFlags));
// Put two samples "out of bounds" above and below.
histogram->Add(5);
@@ -277,8 +292,8 @@ TEST(HistogramTest, BoundsTest) {
// Check to be sure samples land as expected is "correct" buckets.
TEST(HistogramTest, BucketPlacementTest) {
- scoped_refptr<Histogram> histogram = Histogram::FactoryGet(
- "Histogram", 1, 64, 8, Histogram::kNoFlags); // As per header file.
+ Histogram* histogram(Histogram::FactoryGet(
+ "Histogram", 1, 64, 8, Histogram::kNoFlags)); // As per header file.
// Check that we got a nice exponential since there was enough rooom.
EXPECT_EQ(0, histogram->ranges(0));
@@ -314,8 +329,8 @@ TEST(HistogramTest, BucketPlacementTest) {
// out to the base namespace here. We need to be friends to corrupt the
// internals of the histogram and/or sampleset.
TEST(HistogramTest, CorruptSampleCounts) {
- scoped_refptr<Histogram> histogram = Histogram::FactoryGet(
- "Histogram", 1, 64, 8, Histogram::kNoFlags); // As per header file.
+ Histogram* histogram(Histogram::FactoryGet(
+ "Histogram", 1, 64, 8, Histogram::kNoFlags)); // As per header file.
EXPECT_EQ(0, histogram->sample_.redundant_count());
histogram->Add(20); // Add some samples.
@@ -339,8 +354,8 @@ TEST(HistogramTest, CorruptSampleCounts) {
}
TEST(HistogramTest, CorruptBucketBounds) {
- scoped_refptr<Histogram> histogram = Histogram::FactoryGet(
- "Histogram", 1, 64, 8, Histogram::kNoFlags); // As per header file.
+ Histogram* histogram(Histogram::FactoryGet(
+ "Histogram", 1, 64, 8, Histogram::kNoFlags)); // As per header file.
Histogram::SampleSet snapshot;
histogram->SnapshotSample(&snapshot);
diff --git a/base/metrics/stats_counters.cc b/base/metrics/stats_counters.cc
index 958f048..f763220 100644
--- a/base/metrics/stats_counters.cc
+++ b/base/metrics/stats_counters.cc
@@ -9,8 +9,12 @@ namespace base {
StatsCounter::StatsCounter(const std::string& name)
: counter_id_(-1) {
// We prepend the name with 'c:' to indicate that it is a counter.
- name_ = "c:";
- name_.append(name);
+ if (StatsTable::current()) {
+ // TODO(mbelshe): name_ construction is racy and it may corrupt memory for
+ // static.
+ name_ = "c:";
+ name_.append(name);
+ }
}
StatsCounter::~StatsCounter() {
@@ -61,8 +65,12 @@ int* StatsCounter::GetPtr() {
StatsCounterTimer::StatsCounterTimer(const std::string& name) {
// we prepend the name with 't:' to indicate that it is a timer.
- name_ = "t:";
- name_.append(name);
+ if (StatsTable::current()) {
+ // TODO(mbelshe): name_ construction is racy and it may corrupt memory for
+ // static.
+ name_ = "t:";
+ name_.append(name);
+ }
}
StatsCounterTimer::~StatsCounterTimer() {
diff --git a/base/metrics/stats_counters.h b/base/metrics/stats_counters.h
index 2de2b73..f40dcbe 100644
--- a/base/metrics/stats_counters.h
+++ b/base/metrics/stats_counters.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -8,6 +8,7 @@
#include <string>
+#include "base/base_api.h"
#include "base/metrics/stats_table.h"
#include "base/time.h"
@@ -46,14 +47,14 @@ namespace base {
//------------------------------------------------------------------------------
// First provide generic macros, which exist in production as well as debug.
#define STATS_COUNTER(name, delta) do { \
- static base::StatsCounter counter(name); \
+ base::StatsCounter counter(name); \
counter.Add(delta); \
} while (0)
#define SIMPLE_STATS_COUNTER(name) STATS_COUNTER(name, 1)
#define RATE_COUNTER(name, duration) do { \
- static base::StatsRate hit_count(name); \
+ base::StatsRate hit_count(name); \
hit_count.AddTime(duration); \
} while (0)
@@ -74,7 +75,7 @@ namespace base {
//------------------------------------------------------------------------------
// StatsCounter represents a counter in the StatsTable class.
-class StatsCounter {
+class BASE_API StatsCounter {
public:
// Create a StatsCounter object.
explicit StatsCounter(const std::string& name);
@@ -128,7 +129,7 @@ class StatsCounter {
// A StatsCounterTimer is a StatsCounter which keeps a timer during
// the scope of the StatsCounterTimer. On destruction, it will record
// its time measurement.
-class StatsCounterTimer : protected StatsCounter {
+class BASE_API StatsCounterTimer : protected StatsCounter {
public:
// Constructs and starts the timer.
explicit StatsCounterTimer(const std::string& name);
@@ -157,7 +158,7 @@ class StatsCounterTimer : protected StatsCounter {
// A StatsRate is a timer that keeps a count of the number of intervals added so
// that several statistics can be produced:
// min, max, avg, count, total
-class StatsRate : public StatsCounterTimer {
+class BASE_API StatsRate : public StatsCounterTimer {
public:
// Constructs and starts the timer.
explicit StatsRate(const std::string& name);
diff --git a/base/metrics/stats_table.cc b/base/metrics/stats_table.cc
index 0e8d016..488c690 100644
--- a/base/metrics/stats_table.cc
+++ b/base/metrics/stats_table.cc
@@ -5,8 +5,8 @@
#include "base/metrics/stats_table.h"
#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
#include "base/process_util.h"
-#include "base/scoped_ptr.h"
#include "base/shared_memory.h"
#include "base/string_piece.h"
#include "base/string_util.h"
diff --git a/base/metrics/stats_table.h b/base/metrics/stats_table.h
index 94f7463..c8ebae7 100644
--- a/base/metrics/stats_table.h
+++ b/base/metrics/stats_table.h
@@ -23,6 +23,7 @@
#include <string>
+#include "base/base_api.h"
#include "base/basictypes.h"
#include "base/hash_tables.h"
#include "base/synchronization/lock.h"
@@ -30,7 +31,7 @@
namespace base {
-class StatsTable {
+class BASE_API StatsTable {
public:
// Create a new StatsTable.
// If a StatsTable already exists with the specified name, this StatsTable
diff --git a/base/mime_util_xdg.cc b/base/mime_util_xdg.cc
index 4dd7a3e..e510b68 100644
--- a/base/mime_util_xdg.cc
+++ b/base/mime_util_xdg.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -15,16 +15,21 @@
#include "base/file_util.h"
#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/singleton.h"
#include "base/message_loop.h"
-#include "base/scoped_ptr.h"
-#include "base/singleton.h"
#include "base/string_split.h"
#include "base/string_util.h"
+#include "base/synchronization/lock.h"
#include "base/third_party/xdg_mime/xdgmime.h"
#include "base/threading/thread_restrictions.h"
namespace {
+// None of the XDG stuff is thread-safe, so serialize all accesss under
+// this lock.
+base::Lock g_mime_util_xdg_lock;
+
class IconTheme;
class MimeUtilConstants {
@@ -553,11 +558,13 @@ namespace mime_util {
std::string GetFileMimeType(const FilePath& filepath) {
base::ThreadRestrictions::AssertIOAllowed();
+ base::AutoLock scoped_lock(g_mime_util_xdg_lock);
return xdg_mime_get_mime_type_from_file_name(filepath.value().c_str());
}
std::string GetDataMimeType(const std::string& data) {
base::ThreadRestrictions::AssertIOAllowed();
+ base::AutoLock scoped_lock(g_mime_util_xdg_lock);
return xdg_mime_get_mime_type_for_data(data.data(), data.length(), NULL);
}
@@ -585,8 +592,12 @@ FilePath GetMimeIcon(const std::string& mime_type, size_t size) {
std::string icon_name;
FilePath icon_file;
- const char* icon = xdg_mime_get_icon(mime_type.c_str());
- icon_name = std::string(icon ? icon : "");
+ {
+ base::AutoLock scoped_lock(g_mime_util_xdg_lock);
+ const char *icon = xdg_mime_get_icon(mime_type.c_str());
+ icon_name = std::string(icon ? icon : "");
+ }
+
if (icon_name.length())
icon_names.push_back(icon_name);
diff --git a/base/native_library.h b/base/native_library.h
index 6afd06d..2896163 100644
--- a/base/native_library.h
+++ b/base/native_library.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -9,6 +9,7 @@
// This file defines a cross-platform "NativeLibrary" type which represents
// a loadable module.
+#include "base/base_api.h"
#include "build/build_config.h"
#if defined(OS_WIN)
@@ -51,8 +52,11 @@ typedef void* NativeLibrary;
#endif // OS_*
// Loads a native library from disk. Release it with UnloadNativeLibrary when
-// you're done.
-NativeLibrary LoadNativeLibrary(const FilePath& library_path);
+// you're done. Returns NULL on failure.
+// If |err| is not NULL, it may be filled in with an error message on
+// error.
+BASE_API NativeLibrary LoadNativeLibrary(const FilePath& library_path,
+ std::string* error);
#if defined(OS_WIN)
// Loads a native library from disk. Release it with UnloadNativeLibrary when
@@ -60,21 +64,22 @@ NativeLibrary LoadNativeLibrary(const FilePath& library_path);
// This function retrieves the LoadLibrary function exported from kernel32.dll
// and calls it instead of directly calling the LoadLibrary function via the
// import table.
-NativeLibrary LoadNativeLibraryDynamically(const FilePath& library_path);
+BASE_API NativeLibrary LoadNativeLibraryDynamically(
+ const FilePath& library_path);
#endif // OS_WIN
// Unloads a native library.
-void UnloadNativeLibrary(NativeLibrary library);
+BASE_API void UnloadNativeLibrary(NativeLibrary library);
// Gets a function pointer from a native library.
-void* GetFunctionPointerFromNativeLibrary(NativeLibrary library,
- const char* name);
+BASE_API void* GetFunctionPointerFromNativeLibrary(NativeLibrary library,
+ const char* name);
// Returns the full platform specific name for a native library.
// For example:
// "mylib" returns "mylib.dll" on Windows, "libmylib.so" on Linux,
// "mylib.dylib" on Mac.
-string16 GetNativeLibraryName(const string16& name);
+BASE_API string16 GetNativeLibraryName(const string16& name);
} // namespace base
diff --git a/base/native_library_linux.cc b/base/native_library_linux.cc
index e282bce..bcc4ffb 100644
--- a/base/native_library_linux.cc
+++ b/base/native_library_linux.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -14,7 +14,8 @@
namespace base {
// static
-NativeLibrary LoadNativeLibrary(const FilePath& library_path) {
+NativeLibrary LoadNativeLibrary(const FilePath& library_path,
+ std::string* error) {
// dlopen() opens the file off disk.
base::ThreadRestrictions::AssertIOAllowed();
@@ -23,16 +24,8 @@ NativeLibrary LoadNativeLibrary(const FilePath& library_path) {
// http://crbug.com/17943, http://crbug.com/17557, http://crbug.com/36892,
// and http://crbug.com/40794.
void* dl = dlopen(library_path.value().c_str(), RTLD_LAZY);
- if (!dl) {
- std::string error_message = dlerror();
- // Some obsolete plugins depend on libxul or libxpcom.
- // Ignore the error messages when failing to load these.
- if (error_message.find("libxul.so") == std::string::npos &&
- error_message.find("libxpcom.so") == std::string::npos) {
- LOG(ERROR) << "dlopen failed when trying to open " << library_path.value()
- << ": " << error_message;
- }
- }
+ if (!dl && error)
+ *error = dlerror();
return dl;
}
diff --git a/base/native_library_mac.mm b/base/native_library_mac.mm
index 742d92a..9f7a967 100644
--- a/base/native_library_mac.mm
+++ b/base/native_library_mac.mm
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -16,7 +16,8 @@
namespace base {
// static
-NativeLibrary LoadNativeLibrary(const FilePath& library_path) {
+NativeLibrary LoadNativeLibrary(const FilePath& library_path,
+ std::string* error) {
// dlopen() etc. open the file off disk.
if (library_path.Extension() == "dylib" ||
!file_util::DirectoryExists(library_path)) {
diff --git a/base/native_library_win.cc b/base/native_library_win.cc
index b77fbe1..af00cd1 100644
--- a/base/native_library_win.cc
+++ b/base/native_library_win.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -39,7 +39,8 @@ NativeLibrary LoadNativeLibraryHelper(const FilePath& library_path,
}
// static
-NativeLibrary LoadNativeLibrary(const FilePath& library_path) {
+NativeLibrary LoadNativeLibrary(const FilePath& library_path,
+ std::string* error) {
return LoadNativeLibraryHelper(library_path, LoadLibraryW);
}
diff --git a/base/nix/xdg_util.cc b/base/nix/xdg_util.cc
index b39a07d..f824618 100644
--- a/base/nix/xdg_util.cc
+++ b/base/nix/xdg_util.cc
@@ -43,7 +43,8 @@ DesktopEnvironment GetDesktopEnvironment(Environment* env) {
if (env->HasVar("KDE_SESSION_VERSION"))
return DESKTOP_ENVIRONMENT_KDE4;
return DESKTOP_ENVIRONMENT_KDE3;
- } else if (desktop_session.find("xfce") != std::string::npos) {
+ } else if (desktop_session.find("xfce") != std::string::npos ||
+ desktop_session == "xubuntu") {
return DESKTOP_ENVIRONMENT_XFCE;
}
}
diff --git a/base/nss_util.cc b/base/nss_util.cc
deleted file mode 100644
index fe78fe0..0000000
--- a/base/nss_util.cc
+++ /dev/null
@@ -1,436 +0,0 @@
-// 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.
-
-#include "base/nss_util.h"
-#include "base/nss_util_internal.h"
-
-#include <nss.h>
-#include <plarena.h>
-#include <prerror.h>
-#include <prinit.h>
-#include <prtime.h>
-#include <pk11pub.h>
-#include <secmod.h>
-
-#if defined(OS_LINUX)
-#include <linux/nfs_fs.h>
-#include <sys/vfs.h>
-#endif
-
-#include "base/file_util.h"
-#include "base/lazy_instance.h"
-#include "base/logging.h"
-#include "base/stringprintf.h"
-#include "base/threading/thread_restrictions.h"
-
-// USE_NSS means we use NSS for everything crypto-related. If USE_NSS is not
-// defined, such as on Mac and Windows, we use NSS for SSL only -- we don't
-// use NSS for crypto or certificate verification, and we don't use the NSS
-// certificate and key databases.
-#if defined(USE_NSS)
-#include "base/crypto/crypto_module_blocking_password_delegate.h"
-#include "base/environment.h"
-#include "base/scoped_ptr.h"
-#include "base/synchronization/lock.h"
-#endif // defined(USE_NSS)
-
-namespace base {
-
-namespace {
-
-#if defined(USE_NSS)
-FilePath GetDefaultConfigDirectory() {
- FilePath dir = file_util::GetHomeDir();
- if (dir.empty()) {
- LOG(ERROR) << "Failed to get home directory.";
- return dir;
- }
- dir = dir.AppendASCII(".pki").AppendASCII("nssdb");
- if (!file_util::CreateDirectory(dir)) {
- LOG(ERROR) << "Failed to create ~/.pki/nssdb directory.";
- dir.clear();
- }
- return dir;
-}
-
-// On non-chromeos platforms, return the default config directory.
-// On chromeos, return a read-only directory with fake root CA certs for testing
-// (which will not exist on non-testing images). These root CA certs are used
-// by the local Google Accounts server mock we use when testing our login code.
-// If this directory is not present, NSS_Init() will fail. It is up to the
-// caller to failover to NSS_NoDB_Init() at that point.
-FilePath GetInitialConfigDirectory() {
-#if defined(OS_CHROMEOS)
- static const FilePath::CharType kReadOnlyCertDB[] =
- FILE_PATH_LITERAL("/etc/fake_root_ca/nssdb");
- return FilePath(kReadOnlyCertDB);
-#else
- return GetDefaultConfigDirectory();
-#endif // defined(OS_CHROMEOS)
-}
-
-// This callback for NSS forwards all requests to a caller-specified
-// CryptoModuleBlockingPasswordDelegate object.
-char* PKCS11PasswordFunc(PK11SlotInfo* slot, PRBool retry, void* arg) {
- base::CryptoModuleBlockingPasswordDelegate* delegate =
- reinterpret_cast<base::CryptoModuleBlockingPasswordDelegate*>(arg);
- if (delegate) {
- bool cancelled = false;
- std::string password = delegate->RequestPassword(PK11_GetTokenName(slot),
- retry != PR_FALSE,
- &cancelled);
- if (cancelled)
- return NULL;
- char* result = PORT_Strdup(password.c_str());
- password.replace(0, password.size(), password.size(), 0);
- return result;
- }
- DLOG(ERROR) << "PK11 password requested with NULL arg";
- return NULL;
-}
-
-// NSS creates a local cache of the sqlite database if it detects that the
-// filesystem the database is on is much slower than the local disk. The
-// detection doesn't work with the latest versions of sqlite, such as 3.6.22
-// (NSS bug https://bugzilla.mozilla.org/show_bug.cgi?id=578561). So we set
-// the NSS environment variable NSS_SDB_USE_CACHE to "yes" to override NSS's
-// detection when database_dir is on NFS. See http://crbug.com/48585.
-//
-// TODO(wtc): port this function to other USE_NSS platforms. It is defined
-// only for OS_LINUX simply because the statfs structure is OS-specific.
-//
-// Because this function sets an environment variable it must be run before we
-// go multi-threaded.
-void UseLocalCacheOfNSSDatabaseIfNFS(const FilePath& database_dir) {
-#if defined(OS_LINUX)
- struct statfs buf;
- if (statfs(database_dir.value().c_str(), &buf) == 0) {
- if (buf.f_type == NFS_SUPER_MAGIC) {
- scoped_ptr<Environment> env(Environment::Create());
- const char* use_cache_env_var = "NSS_SDB_USE_CACHE";
- if (!env->HasVar(use_cache_env_var))
- env->SetVar(use_cache_env_var, "yes");
- }
- }
-#endif // defined(OS_LINUX)
-}
-
-// Load nss's built-in root certs.
-SECMODModule *InitDefaultRootCerts() {
- const char* kModulePath = "libnssckbi.so";
- char modparams[1024];
- snprintf(modparams, sizeof(modparams),
- "name=\"Root Certs\" library=\"%s\"", kModulePath);
- SECMODModule *root = SECMOD_LoadUserModule(modparams, NULL, PR_FALSE);
- if (root)
- return root;
-
- // Aw, snap. Can't find/load root cert shared library.
- // This will make it hard to talk to anybody via https.
- NOTREACHED();
- return NULL;
-}
-#endif // defined(USE_NSS)
-
-// A singleton to initialize/deinitialize NSPR.
-// Separate from the NSS singleton because we initialize NSPR on the UI thread.
-// Now that we're leaking the singleton, we could merge back with the NSS
-// singleton.
-class NSPRInitSingleton {
- private:
- friend struct DefaultLazyInstanceTraits<NSPRInitSingleton>;
-
- NSPRInitSingleton() {
- PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
- }
-
- // NOTE(willchan): We don't actually execute this code since we leak NSS to
- // prevent non-joinable threads from using NSS after it's already been shut
- // down.
- ~NSPRInitSingleton() {
- PL_ArenaFinish();
- PRStatus prstatus = PR_Cleanup();
- if (prstatus != PR_SUCCESS) {
- LOG(ERROR) << "PR_Cleanup failed; was NSPR initialized on wrong thread?";
- }
- }
-};
-
-LazyInstance<NSPRInitSingleton, LeakyLazyInstanceTraits<NSPRInitSingleton> >
- g_nspr_singleton(LINKER_INITIALIZED);
-
-class NSSInitSingleton {
- public:
-#if defined(OS_CHROMEOS)
- void OpenPersistentNSSDB() {
- if (!chromeos_user_logged_in_) {
- // GetDefaultConfigDirectory causes us to do blocking IO on UI thread.
- // Temporarily allow it until we fix http://crbug.com.70119
- ThreadRestrictions::ScopedAllowIO allow_io;
- chromeos_user_logged_in_ = true;
- real_db_slot_ = OpenUserDB(GetDefaultConfigDirectory(),
- "Real NSS database");
- }
- }
-#endif // defined(OS_CHROMEOS)
-
- bool OpenTestNSSDB(const FilePath& path, const char* description) {
- test_db_slot_ = OpenUserDB(path, description);
- return !!test_db_slot_;
- }
-
- void CloseTestNSSDB() {
- if (test_db_slot_) {
- SECStatus status = SECMOD_CloseUserDB(test_db_slot_);
- if (status != SECSuccess)
- LOG(ERROR) << "SECMOD_CloseUserDB failed: " << PORT_GetError();
- PK11_FreeSlot(test_db_slot_);
- test_db_slot_ = NULL;
- }
- }
-
- PK11SlotInfo* GetDefaultKeySlot() {
- if (test_db_slot_)
- return PK11_ReferenceSlot(test_db_slot_);
- if (real_db_slot_)
- return PK11_ReferenceSlot(real_db_slot_);
- return PK11_GetInternalKeySlot();
- }
-
-#if defined(USE_NSS)
- Lock* write_lock() {
- return &write_lock_;
- }
-#endif // defined(USE_NSS)
-
- private:
- friend struct DefaultLazyInstanceTraits<NSSInitSingleton>;
-
- NSSInitSingleton()
- : real_db_slot_(NULL),
- test_db_slot_(NULL),
- root_(NULL),
- chromeos_user_logged_in_(false) {
- EnsureNSPRInit();
-
- // We *must* have NSS >= 3.12.3. See bug 26448.
- COMPILE_ASSERT(
- (NSS_VMAJOR == 3 && NSS_VMINOR == 12 && NSS_VPATCH >= 3) ||
- (NSS_VMAJOR == 3 && NSS_VMINOR > 12) ||
- (NSS_VMAJOR > 3),
- nss_version_check_failed);
- // Also check the run-time NSS version.
- // NSS_VersionCheck is a >= check, not strict equality.
- if (!NSS_VersionCheck("3.12.3")) {
- // It turns out many people have misconfigured NSS setups, where
- // their run-time NSPR doesn't match the one their NSS was compiled
- // against. So rather than aborting, complain loudly.
- LOG(ERROR) << "NSS_VersionCheck(\"3.12.3\") failed. "
- "We depend on NSS >= 3.12.3, and this error is not fatal "
- "only because many people have busted NSS setups (for "
- "example, using the wrong version of NSPR). "
- "Please upgrade to the latest NSS and NSPR, and if you "
- "still get this error, contact your distribution "
- "maintainer.";
- }
-
- SECStatus status = SECFailure;
-#if !defined(USE_NSS)
- // Use the system certificate store, so initialize NSS without database.
- status = NSS_NoDB_Init(NULL);
- if (status != SECSuccess) {
- LOG(ERROR) << "Error initializing NSS without a persistent "
- "database: NSS error code " << PR_GetError();
- }
-#else
- FilePath database_dir = GetInitialConfigDirectory();
- if (!database_dir.empty()) {
- // This duplicates the work which should have been done in
- // EarlySetupForNSSInit. However, this function is idempotent so there's
- // no harm done.
- UseLocalCacheOfNSSDatabaseIfNFS(database_dir);
-
- // Initialize with a persistent database (likely, ~/.pki/nssdb).
- // Use "sql:" which can be shared by multiple processes safely.
- std::string nss_config_dir =
- StringPrintf("sql:%s", database_dir.value().c_str());
-#if defined(OS_CHROMEOS)
- status = NSS_Init(nss_config_dir.c_str());
-#else
- status = NSS_InitReadWrite(nss_config_dir.c_str());
-#endif
- if (status != SECSuccess) {
- LOG(ERROR) << "Error initializing NSS with a persistent "
- "database (" << nss_config_dir
- << "): NSS error code " << PR_GetError();
- }
- }
- if (status != SECSuccess) {
- LOG(WARNING) << "Initialize NSS without a persistent database "
- "(~/.pki/nssdb).";
- status = NSS_NoDB_Init(NULL);
- if (status != SECSuccess) {
- LOG(ERROR) << "Error initializing NSS without a persistent "
- "database: NSS error code " << PR_GetError();
- return;
- }
- }
-
- PK11_SetPasswordFunc(PKCS11PasswordFunc);
-
- // If we haven't initialized the password for the NSS databases,
- // initialize an empty-string password so that we don't need to
- // log in.
- PK11SlotInfo* slot = PK11_GetInternalKeySlot();
- if (slot) {
- // PK11_InitPin may write to the keyDB, but no other thread can use NSS
- // yet, so we don't need to lock.
- if (PK11_NeedUserInit(slot))
- PK11_InitPin(slot, NULL, NULL);
- PK11_FreeSlot(slot);
- }
-
- root_ = InitDefaultRootCerts();
-#endif // !defined(USE_NSS)
- }
-
- // NOTE(willchan): We don't actually execute this code since we leak NSS to
- // prevent non-joinable threads from using NSS after it's already been shut
- // down.
- ~NSSInitSingleton() {
- if (real_db_slot_) {
- SECMOD_CloseUserDB(real_db_slot_);
- PK11_FreeSlot(real_db_slot_);
- real_db_slot_ = NULL;
- }
- CloseTestNSSDB();
- if (root_) {
- SECMOD_UnloadUserModule(root_);
- SECMOD_DestroyModule(root_);
- root_ = NULL;
- }
-
- SECStatus status = NSS_Shutdown();
- if (status != SECSuccess) {
- // We VLOG(1) because this failure is relatively harmless (leaking, but
- // we're shutting down anyway).
- VLOG(1) << "NSS_Shutdown failed; see "
- "http://code.google.com/p/chromium/issues/detail?id=4609";
- }
- }
-
- static PK11SlotInfo* OpenUserDB(const FilePath& path,
- const char* description) {
- const std::string modspec =
- StringPrintf("configDir='sql:%s' tokenDescription='%s'",
- path.value().c_str(), description);
- PK11SlotInfo* db_slot = SECMOD_OpenUserDB(modspec.c_str());
- if (db_slot) {
- if (PK11_NeedUserInit(db_slot))
- PK11_InitPin(db_slot, NULL, NULL);
- }
- else {
- LOG(ERROR) << "Error opening persistent database (" << modspec
- << "): NSS error code " << PR_GetError();
- }
- return db_slot;
- }
-
- PK11SlotInfo* real_db_slot_; // Overrides internal key slot if non-NULL.
- PK11SlotInfo* test_db_slot_; // Overrides internal key slot and real_db_slot_
- SECMODModule *root_;
- bool chromeos_user_logged_in_;
-#if defined(USE_NSS)
- // TODO(davidben): When https://bugzilla.mozilla.org/show_bug.cgi?id=564011
- // is fixed, we will no longer need the lock.
- Lock write_lock_;
-#endif // defined(USE_NSS)
-};
-
-LazyInstance<NSSInitSingleton, LeakyLazyInstanceTraits<NSSInitSingleton> >
- g_nss_singleton(LINKER_INITIALIZED);
-
-} // namespace
-
-#if defined(USE_NSS)
-void EarlySetupForNSSInit() {
- FilePath database_dir = GetInitialConfigDirectory();
- if (!database_dir.empty())
- UseLocalCacheOfNSSDatabaseIfNFS(database_dir);
-}
-#endif
-
-void EnsureNSPRInit() {
- g_nspr_singleton.Get();
-}
-
-void EnsureNSSInit() {
- // Initializing SSL causes us to do blocking IO.
- // Temporarily allow it until we fix
- // http://code.google.com/p/chromium/issues/detail?id=59847
- ThreadRestrictions::ScopedAllowIO allow_io;
- g_nss_singleton.Get();
-}
-
-bool CheckNSSVersion(const char* version) {
- return !!NSS_VersionCheck(version);
-}
-
-#if defined(USE_NSS)
-bool OpenTestNSSDB(const FilePath& path, const char* description) {
- return g_nss_singleton.Get().OpenTestNSSDB(path, description);
-}
-
-void CloseTestNSSDB() {
- g_nss_singleton.Get().CloseTestNSSDB();
-}
-
-Lock* GetNSSWriteLock() {
- return g_nss_singleton.Get().write_lock();
-}
-
-AutoNSSWriteLock::AutoNSSWriteLock() : lock_(GetNSSWriteLock()) {
- // May be NULL if the lock is not needed in our version of NSS.
- if (lock_)
- lock_->Acquire();
-}
-
-AutoNSSWriteLock::~AutoNSSWriteLock() {
- if (lock_) {
- lock_->AssertAcquired();
- lock_->Release();
- }
-}
-#endif // defined(USE_NSS)
-
-#if defined(OS_CHROMEOS)
-void OpenPersistentNSSDB() {
- g_nss_singleton.Get().OpenPersistentNSSDB();
-}
-#endif
-
-// TODO(port): Implement this more simply. We can convert by subtracting an
-// offset (the difference between NSPR's and base::Time's epochs).
-Time PRTimeToBaseTime(PRTime prtime) {
- PRExplodedTime prxtime;
- PR_ExplodeTime(prtime, PR_GMTParameters, &prxtime);
-
- Time::Exploded exploded;
- exploded.year = prxtime.tm_year;
- exploded.month = prxtime.tm_month + 1;
- exploded.day_of_week = prxtime.tm_wday;
- exploded.day_of_month = prxtime.tm_mday;
- exploded.hour = prxtime.tm_hour;
- exploded.minute = prxtime.tm_min;
- exploded.second = prxtime.tm_sec;
- exploded.millisecond = prxtime.tm_usec / 1000;
-
- return Time::FromUTCExploded(exploded);
-}
-
-PK11SlotInfo* GetDefaultNSSKeySlot() {
- return g_nss_singleton.Get().GetDefaultKeySlot();
-}
-
-} // namespace base
diff --git a/base/nss_util.h b/base/nss_util.h
deleted file mode 100644
index 10bbdfb..0000000
--- a/base/nss_util.h
+++ /dev/null
@@ -1,85 +0,0 @@
-// 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 BASE_NSS_UTIL_H_
-#define BASE_NSS_UTIL_H_
-#pragma once
-
-#include "base/basictypes.h"
-
-#if defined(USE_NSS)
-class FilePath;
-#endif // defined(USE_NSS)
-
-// This file specifically doesn't depend on any NSS or NSPR headers because it
-// is included by various (non-crypto) parts of chrome to call the
-// initialization functions.
-namespace base {
-
-class Lock;
-class Time;
-
-#if defined(USE_NSS)
-// EarlySetupForNSSInit performs lightweight setup which must occur before the
-// process goes multithreaded. This does not initialise NSS. For test, see
-// EnsureNSSInit.
-void EarlySetupForNSSInit();
-#endif
-
-// Initialize NRPR if it isn't already initialized. This function is
-// thread-safe, and NSPR will only ever be initialized once. NSPR will be
-// properly shut down on program exit.
-void EnsureNSPRInit();
-
-// Initialize NSS if it isn't already initialized. This must be called before
-// any other NSS functions. This function is thread-safe, and NSS will only
-// ever be initialized once. NSS will be properly shut down on program exit.
-void EnsureNSSInit();
-
-// Check if the current NSS version is greater than or equals to |version|.
-// A sample version string is "3.12.3".
-bool CheckNSSVersion(const char* version);
-
-#if defined(OS_CHROMEOS)
-// Open the r/w nssdb that's stored inside the user's encrypted home directory.
-void OpenPersistentNSSDB();
-#endif
-
-// Convert a NSS PRTime value into a base::Time object.
-// We use a int64 instead of PRTime here to avoid depending on NSPR headers.
-Time PRTimeToBaseTime(int64 prtime);
-
-#if defined(USE_NSS)
-// Exposed for unittests only. |path| should be an existing directory under
-// which the DB files will be placed. |description| is a user-visible name for
-// the DB, as a utf8 string, which will be truncated at 32 bytes.
-bool OpenTestNSSDB(const FilePath& path, const char* description);
-void CloseTestNSSDB();
-
-// NSS has a bug which can cause a deadlock or stall in some cases when writing
-// to the certDB and keyDB. It also has a bug which causes concurrent key pair
-// generations to scribble over each other. To work around this, we synchronize
-// writes to the NSS databases with a global lock. The lock is hidden beneath a
-// function for easy disabling when the bug is fixed. Callers should allow for
-// it to return NULL in the future.
-//
-// See https://bugzilla.mozilla.org/show_bug.cgi?id=564011
-Lock* GetNSSWriteLock();
-
-// A helper class that acquires the NSS write Lock while the AutoNSSWriteLock
-// is in scope.
-class AutoNSSWriteLock {
- public:
- AutoNSSWriteLock();
- ~AutoNSSWriteLock();
- private:
- Lock *lock_;
- DISALLOW_COPY_AND_ASSIGN(AutoNSSWriteLock);
-};
-
-#endif // defined(USE_NSS)
-
-} // namespace base
-
-#endif // BASE_NSS_UTIL_H_
diff --git a/base/nss_util_internal.h b/base/nss_util_internal.h
deleted file mode 100644
index 139740b..0000000
--- a/base/nss_util_internal.h
+++ /dev/null
@@ -1,22 +0,0 @@
-// 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 BASE_NSS_SLOT_UTIL_H_
-#define BASE_NSS_SLOT_UTIL_H_
-#pragma once
-
-#include <secmodt.h>
-
-// These functions return a type defined in an NSS header, and so cannot be
-// declared in nss_util.h. Hence, they are declared here.
-
-namespace base {
-
-// Returns a reference to the default NSS key slot. Caller must release
-// reference with PK11_FreeSlot.
-PK11SlotInfo* GetDefaultNSSKeySlot();
-
-} // namespace base
-
-#endif // BASE_NSS_UTIL_H_
diff --git a/base/observer_list_threadsafe.h b/base/observer_list_threadsafe.h
index 47a662e..43c6913 100644
--- a/base/observer_list_threadsafe.h
+++ b/base/observer_list_threadsafe.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -12,9 +12,9 @@
#include "base/basictypes.h"
#include "base/callback.h"
#include "base/logging.h"
+#include "base/memory/ref_counted.h"
#include "base/message_loop.h"
#include "base/observer_list.h"
-#include "base/ref_counted.h"
#include "base/task.h"
///////////////////////////////////////////////////////////////////////////////
diff --git a/base/observer_list_unittest.cc b/base/observer_list_unittest.cc
index 652d358..d313367 100644
--- a/base/observer_list_unittest.cc
+++ b/base/observer_list_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -7,8 +7,8 @@
#include <vector>
+#include "base/memory/ref_counted.h"
#include "base/message_loop.h"
-#include "base/ref_counted.h"
#include "base/threading/platform_thread.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/base/openssl_util.cc b/base/openssl_util.cc
deleted file mode 100644
index 931485a..0000000
--- a/base/openssl_util.cc
+++ /dev/null
@@ -1,113 +0,0 @@
-// 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.
-
-#include "base/openssl_util.h"
-
-#include <openssl/err.h>
-#include <openssl/ssl.h>
-
-#include "base/logging.h"
-#include "base/scoped_vector.h"
-#include "base/singleton.h"
-#include "base/string_piece.h"
-#include "base/synchronization/lock.h"
-
-namespace base {
-
-namespace {
-
-unsigned long CurrentThreadId() {
- return static_cast<unsigned long>(PlatformThread::CurrentId());
-}
-
-// Singleton for initializing and cleaning up the OpenSSL library.
-class OpenSSLInitSingleton {
- public:
- static OpenSSLInitSingleton* GetInstance() {
- // We allow the SSL environment to leak for multiple reasons:
- // - it is used from a non-joinable worker thread that is not stopped on
- // shutdown, hence may still be using OpenSSL library after the AtExit
- // runner has completed.
- // - There are other OpenSSL related singletons (e.g. the client socket
- // context) who's cleanup depends on the global environment here, but
- // we can't control the order the AtExit handlers will run in so
- // allowing the global environment to leak at least ensures it is
- // available for those other singletons to reliably cleanup.
- return Singleton<OpenSSLInitSingleton,
- LeakySingletonTraits<OpenSSLInitSingleton> >::get();
- }
- private:
- friend struct DefaultSingletonTraits<OpenSSLInitSingleton>;
- OpenSSLInitSingleton() {
- SSL_load_error_strings();
- SSL_library_init();
- OpenSSL_add_all_algorithms();
- int num_locks = CRYPTO_num_locks();
- locks_.reserve(num_locks);
- for (int i = 0; i < num_locks; ++i)
- locks_.push_back(new base::Lock());
- CRYPTO_set_locking_callback(LockingCallback);
- CRYPTO_set_id_callback(CurrentThreadId);
- }
-
- ~OpenSSLInitSingleton() {
- CRYPTO_set_locking_callback(NULL);
- EVP_cleanup();
- ERR_free_strings();
- }
-
- static void LockingCallback(int mode, int n, const char* file, int line) {
- OpenSSLInitSingleton::GetInstance()->OnLockingCallback(mode, n, file, line);
- }
-
- void OnLockingCallback(int mode, int n, const char* file, int line) {
- CHECK_LT(static_cast<size_t>(n), locks_.size());
- if (mode & CRYPTO_LOCK)
- locks_[n]->Acquire();
- else
- locks_[n]->Release();
- }
-
- // These locks are used and managed by OpenSSL via LockingCallback().
- ScopedVector<base::Lock> locks_;
-
- DISALLOW_COPY_AND_ASSIGN(OpenSSLInitSingleton);
-};
-
-// Callback routine for OpenSSL to print error messages. |str| is a
-// NULL-terminated string of length |len| containing diagnostic information
-// such as the library, function and reason for the error, the file and line
-// where the error originated, plus potentially any context-specific
-// information about the error. |context| contains a pointer to user-supplied
-// data, which is currently unused.
-// If this callback returns a value <= 0, OpenSSL will stop processing the
-// error queue and return, otherwise it will continue calling this function
-// until all errors have been removed from the queue.
-int OpenSSLErrorCallback(const char* str, size_t len, void* context) {
- DVLOG(1) << "\t" << StringPiece(str, len);
- return 1;
-}
-
-} // namespace
-
-void EnsureOpenSSLInit() {
- (void)OpenSSLInitSingleton::GetInstance();
-}
-
-void ClearOpenSSLERRStack(const tracked_objects::Location& location) {
- if (logging::DEBUG_MODE && VLOG_IS_ON(1)) {
- int error_num = ERR_peek_error();
- if (error_num == 0)
- return;
-
- std::string message;
- location.Write(true, true, &message);
- DVLOG(1) << "OpenSSL ERR_get_error stack from " << message;
- ERR_print_errors_cb(&OpenSSLErrorCallback, NULL);
- } else {
- ERR_clear_error();
- }
-}
-
-} // namespace base
diff --git a/base/path_service.cc b/base/path_service.cc
index 117feb5..e72ae7d 100644
--- a/base/path_service.cc
+++ b/base/path_service.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -171,7 +171,7 @@ bool PathService::Get(int key, FilePath* result) {
PathData* path_data = GetPathData();
DCHECK(path_data);
DCHECK(result);
- DCHECK(key >= base::DIR_CURRENT);
+ DCHECK_GE(key, base::DIR_CURRENT);
// special case the current directory because it can never be cached
if (key == base::DIR_CURRENT)
@@ -208,7 +208,7 @@ bool PathService::Get(int key, FilePath* result) {
bool PathService::Override(int key, const FilePath& path) {
PathData* path_data = GetPathData();
DCHECK(path_data);
- DCHECK(key > base::DIR_CURRENT) << "invalid path key";
+ DCHECK_GT(key, base::DIR_CURRENT) << "invalid path key";
FilePath file_path = path;
@@ -241,7 +241,7 @@ void PathService::RegisterProvider(ProviderFunc func, int key_start,
int key_end) {
PathData* path_data = GetPathData();
DCHECK(path_data);
- DCHECK(key_end > key_start);
+ DCHECK_GT(key_end, key_start);
base::AutoLock scoped_lock(path_data->lock);
diff --git a/base/path_service.h b/base/path_service.h
index edaa5e3..284fbf7 100644
--- a/base/path_service.h
+++ b/base/path_service.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -6,18 +6,18 @@
#define BASE_PATH_SERVICE_H_
#pragma once
-#include "build/build_config.h"
-
#include <string>
+#include "base/base_api.h"
#include "base/base_paths.h"
+#include "build/build_config.h"
class FilePath;
// The path service is a global table mapping keys to file system paths. It is
// OK to use this service from multiple threads.
//
-class PathService {
+class BASE_API PathService {
public:
// Retrieves a path to a special directory or file and places it into the
// string pointed to by 'path'. If you ask for a directory it is guaranteed
diff --git a/base/pickle.cc b/base/pickle.cc
index 116d3f1..afe35db 100644
--- a/base/pickle.cc
+++ b/base/pickle.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -33,7 +33,7 @@ Pickle::Pickle(int header_size)
header_size_(AlignInt(header_size, sizeof(uint32))),
capacity_(0),
variable_buffer_offset_(0) {
- DCHECK(static_cast<size_t>(header_size) >= sizeof(Header));
+ DCHECK_GE(static_cast<size_t>(header_size), sizeof(Header));
DCHECK(header_size <= kPayloadUnit);
Resize(kPayloadUnit);
header_->payload_size = 0;
diff --git a/base/pickle.h b/base/pickle.h
index 9d449ae..20878e0 100644
--- a/base/pickle.h
+++ b/base/pickle.h
@@ -8,6 +8,7 @@
#include <string>
+#include "base/base_api.h"
#include "base/basictypes.h"
#include "base/gtest_prod_util.h"
#include "base/logging.h"
@@ -30,7 +31,7 @@
// space is controlled by the header_size parameter passed to the Pickle
// constructor.
//
-class Pickle {
+class BASE_API Pickle {
public:
// Initialize a Pickle object using the default header size.
Pickle();
diff --git a/base/pickle_unittest.cc b/base/pickle_unittest.cc
index 51330c7..07be5e3 100644
--- a/base/pickle_unittest.cc
+++ b/base/pickle_unittest.cc
@@ -1,12 +1,12 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
#include <string>
#include "base/basictypes.h"
+#include "base/memory/scoped_ptr.h"
#include "base/pickle.h"
-#include "base/scoped_ptr.h"
#include "base/string16.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/base/platform_file.h b/base/platform_file.h
index dd3028b..461b060 100644
--- a/base/platform_file.h
+++ b/base/platform_file.h
@@ -6,16 +6,17 @@
#define BASE_PLATFORM_FILE_H_
#pragma once
-#include "base/basictypes.h"
#include "build/build_config.h"
-#include "base/time.h"
#if defined(OS_WIN)
#include <windows.h>
#endif
#include <string>
-class FilePath;
+#include "base/base_api.h"
+#include "base/basictypes.h"
+#include "base/file_path.h"
+#include "base/time.h"
namespace base {
@@ -41,7 +42,8 @@ enum PlatformFileFlags {
PLATFORM_FILE_HIDDEN = 1024, // Used on Windows only
PLATFORM_FILE_DELETE_ON_CLOSE = 2048,
PLATFORM_FILE_TRUNCATE = 4096,
- PLATFORM_FILE_WRITE_ATTRIBUTES = 8192 // Used on Windows only
+ PLATFORM_FILE_WRITE_ATTRIBUTES = 8192, // Used on Windows only
+ PLATFORM_FILE_ENUMERATE = 16384, // May enumerate directory
};
// PLATFORM_FILE_ERROR_ACCESS_DENIED is returned when a call fails because of
@@ -63,6 +65,7 @@ enum PlatformFileError {
PLATFORM_FILE_ERROR_ABORT = -12,
PLATFORM_FILE_ERROR_NOT_A_FILE = -13,
PLATFORM_FILE_ERROR_NOT_EMPTY = -14,
+ PLATFORM_FILE_ERROR_INVALID_URL = -15,
};
// Used to hold information about a given file.
@@ -70,7 +73,7 @@ enum PlatformFileError {
// make sure to update all functions that use it in file_util_{win|posix}.cc
// too, and the ParamTraits<base::PlatformFileInfo> implementation in
// chrome/common/common_param_traits.cc.
-struct PlatformFileInfo {
+struct BASE_API PlatformFileInfo {
PlatformFileInfo();
~PlatformFileInfo();
@@ -96,42 +99,39 @@ struct PlatformFileInfo {
// Creates or opens the given file. If PLATFORM_FILE_OPEN_ALWAYS is used, and
// |created| is provided, |created| will be set to true if the file was created
// or to false in case the file was just opened. |error_code| can be NULL.
-PlatformFile CreatePlatformFile(const FilePath& name,
- int flags,
- bool* created,
- PlatformFileError* error_code);
-// Deprecated.
-PlatformFile CreatePlatformFile(const std::wstring& name,
- int flags,
- bool* created);
+BASE_API PlatformFile CreatePlatformFile(const FilePath& name,
+ int flags,
+ bool* created,
+ PlatformFileError* error_code);
// Closes a file handle. Returns |true| on success and |false| otherwise.
-bool ClosePlatformFile(PlatformFile file);
+BASE_API bool ClosePlatformFile(PlatformFile file);
// Reads the given number of bytes (or until EOF is reached) starting with the
// given offset. Returns the number of bytes read, or -1 on error.
-int ReadPlatformFile(PlatformFile file, int64 offset, char* data, int size);
+BASE_API int ReadPlatformFile(PlatformFile file, int64 offset,
+ char* data, int size);
// Writes the given buffer into the file at the given offset, overwritting any
// data that was previously there. Returns the number of bytes written, or -1
// on error.
-int WritePlatformFile(PlatformFile file, int64 offset,
- const char* data, int size);
+BASE_API int WritePlatformFile(PlatformFile file, int64 offset,
+ const char* data, int size);
// Truncates the given file to the given length. If |length| is greater than
// the current size of the file, the file is extended with zeros. If the file
// doesn't exist, |false| is returned.
-bool TruncatePlatformFile(PlatformFile file, int64 length);
+BASE_API bool TruncatePlatformFile(PlatformFile file, int64 length);
// Flushes the buffers of the given file.
-bool FlushPlatformFile(PlatformFile file);
+BASE_API bool FlushPlatformFile(PlatformFile file);
// Touches the given file.
-bool TouchPlatformFile(PlatformFile file, const Time& last_access_time,
- const Time& last_modified_time);
+BASE_API bool TouchPlatformFile(PlatformFile file, const Time& last_access_time,
+ const Time& last_modified_time);
// Returns some information for the given file.
-bool GetPlatformFileInfo(PlatformFile file, PlatformFileInfo* info);
+BASE_API bool GetPlatformFileInfo(PlatformFile file, PlatformFileInfo* info);
// Use this class to pass ownership of a PlatformFile to a receiver that may or
// may not want to accept it. This class does not own the storage for the
@@ -153,7 +153,7 @@ bool GetPlatformFileInfo(PlatformFile file, PlatformFileInfo* info);
// ClosePlatformFile(file);
// }
//
-class PassPlatformFile {
+class BASE_API PassPlatformFile {
public:
explicit PassPlatformFile(PlatformFile* value) : value_(value) {
}
diff --git a/base/platform_file_posix.cc b/base/platform_file_posix.cc
index 4e20e25..893997a 100644
--- a/base/platform_file_posix.cc
+++ b/base/platform_file_posix.cc
@@ -45,8 +45,7 @@ PlatformFile CreatePlatformFile(const FilePath& name, int flags,
!(flags & PLATFORM_FILE_OPEN_ALWAYS)) {
NOTREACHED();
errno = EOPNOTSUPP;
- if (error_code)
- *error_code = PLATFORM_FILE_ERROR_FAILED;
+ *error_code = error_code ? PLATFORM_FILE_ERROR_FAILED : PLATFORM_FILE_OK;
return kInvalidPlatformFileValue;
}
@@ -67,7 +66,8 @@ PlatformFile CreatePlatformFile(const FilePath& name, int flags,
COMPILE_ASSERT(O_RDONLY == 0, O_RDONLY_must_equal_zero);
- int descriptor = open(name.value().c_str(), open_flags, S_IRUSR | S_IWUSR);
+ int descriptor =
+ HANDLE_EINTR(open(name.value().c_str(), open_flags, S_IRUSR | S_IWUSR));
if (flags & PLATFORM_FILE_OPEN_ALWAYS) {
if (descriptor > 0) {
@@ -79,7 +79,8 @@ PlatformFile CreatePlatformFile(const FilePath& name, int flags,
flags & PLATFORM_FILE_EXCLUSIVE_WRITE) {
open_flags |= O_EXCL; // together with O_CREAT implies O_NOFOLLOW
}
- descriptor = open(name.value().c_str(), open_flags, S_IRUSR | S_IWUSR);
+ descriptor = HANDLE_EINTR(
+ open(name.value().c_str(), open_flags, S_IRUSR | S_IWUSR));
if (created && descriptor > 0)
*created = true;
}
@@ -134,14 +135,8 @@ PlatformFile CreatePlatformFile(const FilePath& name, int flags,
return descriptor;
}
-PlatformFile CreatePlatformFile(const std::wstring& name, int flags,
- bool* created) {
- return CreatePlatformFile(FilePath::FromWStringHack(name), flags,
- created, NULL);
-}
-
bool ClosePlatformFile(PlatformFile file) {
- return !close(file);
+ return !HANDLE_EINTR(close(file));
}
int ReadPlatformFile(PlatformFile file, int64 offset, char* data, int size) {
@@ -164,7 +159,7 @@ bool TruncatePlatformFile(PlatformFile file, int64 length) {
}
bool FlushPlatformFile(PlatformFile file) {
- return !fsync(file);
+ return !HANDLE_EINTR(fsync(file));
}
bool TouchPlatformFile(PlatformFile file, const base::Time& last_access_time,
diff --git a/base/platform_file_unittest.cc b/base/platform_file_unittest.cc
index e54ab61..dac2956 100644
--- a/base/platform_file_unittest.cc
+++ b/base/platform_file_unittest.cc
@@ -1,10 +1,10 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
#include "base/file_util.h"
+#include "base/memory/scoped_temp_dir.h"
#include "base/platform_file.h"
-#include "base/scoped_temp_dir.h"
#include "base/time.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/base/platform_file_win.cc b/base/platform_file_win.cc
index f9eb234..0cb3e53 100644
--- a/base/platform_file_win.cc
+++ b/base/platform_file_win.cc
@@ -104,12 +104,6 @@ PlatformFile CreatePlatformFile(const FilePath& name,
return file;
}
-PlatformFile CreatePlatformFile(const std::wstring& name, int flags,
- bool* created) {
- return CreatePlatformFile(FilePath::FromWStringHack(name), flags,
- created, NULL);
-}
-
bool ClosePlatformFile(PlatformFile file) {
base::ThreadRestrictions::AssertIOAllowed();
return (CloseHandle(file) != 0);
diff --git a/base/process.h b/base/process.h
index 32f5131..9b1519a 100644
--- a/base/process.h
+++ b/base/process.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -6,6 +6,7 @@
#define BASE_PROCESS_H_
#pragma once
+#include "base/base_api.h"
#include "base/basictypes.h"
#include "build/build_config.h"
@@ -24,11 +25,13 @@ typedef HANDLE ProcessHandle;
typedef DWORD ProcessId;
typedef HANDLE UserTokenHandle;
const ProcessHandle kNullProcessHandle = NULL;
+const ProcessId kNullProcessId = 0;
#elif defined(OS_POSIX)
// On POSIX, our ProcessHandle will just be the PID.
typedef pid_t ProcessHandle;
typedef pid_t ProcessId;
const ProcessHandle kNullProcessHandle = 0;
+const ProcessId kNullProcessId = 0;
#endif // defined(OS_WIN)
#if defined(OS_POSIX) && !defined(OS_MACOSX)
@@ -37,7 +40,7 @@ const ProcessHandle kNullProcessHandle = 0;
const int kUnsetProcessPriority = 256;
#endif
-class Process {
+class BASE_API Process {
public:
Process() : process_(kNullProcessHandle) {
#if defined(OS_POSIX) && !defined(OS_MACOSX)
diff --git a/base/process_linux.cc b/base/process_linux.cc
index 14c2424..dfdc20e 100644
--- a/base/process_linux.cc
+++ b/base/process_linux.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -7,7 +7,20 @@
#include <errno.h>
#include <sys/resource.h>
+#include "base/file_util.h"
#include "base/logging.h"
+#include "base/stringprintf.h"
+
+#if defined(OS_CHROMEOS)
+static bool use_cgroups = false;
+static bool cgroups_inited = false;
+static const char kForegroundTasks[] =
+ "/tmp/cgroup/cpu/chrome_renderers/foreground/tasks";
+static const char kBackgroundTasks[] =
+ "/tmp/cgroup/cpu/chrome_renderers/background/tasks";
+static FilePath foreground_tasks;
+static FilePath background_tasks;
+#endif
namespace base {
@@ -28,6 +41,53 @@ bool Process::IsProcessBackgrounded() const {
bool Process::SetProcessBackgrounded(bool background) {
DCHECK(process_);
+#if defined(OS_CHROMEOS)
+ // Check for cgroups files. ChromeOS supports these by default. It creates
+ // a cgroup mount in /tmp/cgroup and then configures two cpu task groups,
+ // one contains at most a single foreground renderer and the other contains
+ // all background renderers. This allows us to limit the impact of background
+ // renderers on foreground ones to a greater level than simple renicing.
+ if (!cgroups_inited) {
+ cgroups_inited = true;
+ foreground_tasks = FilePath(kForegroundTasks);
+ background_tasks = FilePath(kBackgroundTasks);
+ file_util::FileSystemType foreground_type;
+ file_util::FileSystemType background_type;
+ use_cgroups =
+ file_util::GetFileSystemType(foreground_tasks, &foreground_type) &&
+ file_util::GetFileSystemType(background_tasks, &background_type) &&
+ foreground_type == file_util::FILE_SYSTEM_CGROUP &&
+ background_type == file_util::FILE_SYSTEM_CGROUP;
+ }
+
+ if (use_cgroups) {
+ if (background) {
+ std::string pid = StringPrintf("%d", process_);
+ if (file_util::WriteFile(background_tasks, pid.c_str(), pid.size()) > 0) {
+ // With cgroups there's no real notion of priority as an int, but this
+ // will ensure we only move renderers back to the foreground group
+ // if we've ever put them in the background one.
+ saved_priority_ = 0;
+ return true;
+ } else {
+ return false;
+ }
+ } else {
+ if (saved_priority_ == kUnsetProcessPriority) {
+ // Can't restore if we were never backgrounded.
+ return false;
+ }
+ std::string pid = StringPrintf("%d", process_);
+ if (file_util::WriteFile(foreground_tasks, pid.c_str(), pid.size()) > 0) {
+ saved_priority_ = kUnsetProcessPriority;
+ return true;
+ } else {
+ return false;
+ }
+ }
+ }
+#endif // OS_CHROMEOS
+
if (background) {
// We won't be able to raise the priority if we don't have the right rlimit.
// The limit may be adjusted in /etc/security/limits.conf for PAM systems.
diff --git a/base/process_util.h b/base/process_util.h
index 29b08ca..bdf9b9e 100644
--- a/base/process_util.h
+++ b/base/process_util.h
@@ -33,6 +33,7 @@ typedef struct _malloc_zone_t malloc_zone_t;
#include <utility>
#include <vector>
+#include "base/base_api.h"
#include "base/file_descriptor_shuffle.h"
#include "base/file_path.h"
#include "base/process.h"
@@ -126,18 +127,19 @@ enum TerminationStatus {
TERMINATION_STATUS_ABNORMAL_TERMINATION, // non-zero exit status
TERMINATION_STATUS_PROCESS_WAS_KILLED, // e.g. SIGKILL or task manager kill
TERMINATION_STATUS_PROCESS_CRASHED, // e.g. Segmentation fault
- TERMINATION_STATUS_STILL_RUNNING // child hasn't exited yet
+ TERMINATION_STATUS_STILL_RUNNING, // child hasn't exited yet
+ TERMINATION_STATUS_MAX_ENUM
};
// Returns the id of the current process.
-ProcessId GetCurrentProcId();
+BASE_API ProcessId GetCurrentProcId();
// Returns the ProcessHandle of the current process.
-ProcessHandle GetCurrentProcessHandle();
+BASE_API ProcessHandle GetCurrentProcessHandle();
// Converts a PID to a process handle. This handle must be closed by
// CloseProcessHandle when you are done with it. Returns true on success.
-bool OpenProcessHandle(ProcessId pid, ProcessHandle* handle);
+BASE_API bool OpenProcessHandle(ProcessId pid, ProcessHandle* handle);
// Converts a PID to a process handle. On Windows the handle is opened
// with more access rights and must only be used by trusted code.
@@ -145,21 +147,21 @@ bool OpenProcessHandle(ProcessId pid, ProcessHandle* handle);
// on success.
// TODO(sanjeevr): Replace all calls to OpenPrivilegedProcessHandle with the
// more specific OpenProcessHandleWithAccess method and delete this.
-bool OpenPrivilegedProcessHandle(ProcessId pid, ProcessHandle* handle);
+BASE_API bool OpenPrivilegedProcessHandle(ProcessId pid, ProcessHandle* handle);
// Converts a PID to a process handle using the desired access flags. Use a
// combination of the kProcessAccess* flags defined above for |access_flags|.
-bool OpenProcessHandleWithAccess(ProcessId pid,
- uint32 access_flags,
- ProcessHandle* handle);
+BASE_API bool OpenProcessHandleWithAccess(ProcessId pid,
+ uint32 access_flags,
+ ProcessHandle* handle);
// Closes the process handle opened by OpenProcessHandle.
-void CloseProcessHandle(ProcessHandle process);
+BASE_API void CloseProcessHandle(ProcessHandle process);
// Returns the unique ID for the specified process. This is functionally the
// same as Windows' GetProcessId(), but works on versions of Windows before
// Win XP SP1 as well.
-ProcessId GetProcId(ProcessHandle process);
+BASE_API ProcessId GetProcId(ProcessHandle process);
#if defined(OS_LINUX)
// Returns the path to the executable of the given process.
@@ -199,7 +201,8 @@ enum IntegrityLevel {
// Determine the integrity level of the specified process. Returns false
// if the system does not support integrity levels (pre-Vista) or in the case
// of an underlying system failure.
-bool GetProcessIntegrityLevel(ProcessHandle process, IntegrityLevel *level);
+BASE_API bool GetProcessIntegrityLevel(ProcessHandle process,
+ IntegrityLevel *level);
// Runs the given application name with the given command line. Normally, the
// first command line argument should be the path to the process, and don't
@@ -215,15 +218,15 @@ bool GetProcessIntegrityLevel(ProcessHandle process, IntegrityLevel *level);
// stored there on a successful launch.
// NOTE: In this case, the caller is responsible for closing the handle so
// that it doesn't leak!
-bool LaunchApp(const std::wstring& cmdline,
- bool wait, bool start_hidden, ProcessHandle* process_handle);
+BASE_API bool LaunchApp(const std::wstring& cmdline,
+ bool wait, bool start_hidden,
+ ProcessHandle* process_handle);
// Same as LaunchApp, except allows the new process to inherit handles of the
// parent process.
-bool LaunchAppWithHandleInheritance(const std::wstring& cmdline,
- bool wait,
- bool start_hidden,
- ProcessHandle* process_handle);
+BASE_API bool LaunchAppWithHandleInheritance(const std::wstring& cmdline,
+ bool wait, bool start_hidden,
+ ProcessHandle* process_handle);
// Runs the given application name with the given command line as if the user
// represented by |token| had launched it. The caveats about |cmdline| and
@@ -235,15 +238,18 @@ bool LaunchAppWithHandleInheritance(const std::wstring& cmdline,
// To avoid hard to diagnose problems, this function internally loads the
// environment variables associated with the user and if this operation fails
// the entire call fails as well.
-bool LaunchAppAsUser(UserTokenHandle token, const std::wstring& cmdline,
- bool start_hidden, ProcessHandle* process_handle);
+BASE_API bool LaunchAppAsUser(UserTokenHandle token,
+ const std::wstring& cmdline,
+ bool start_hidden,
+ ProcessHandle* process_handle);
// Has the same behavior as LaunchAppAsUser, but offers the boolean option to
// use an empty string for the desktop name and a boolean for allowing the
// child process to inherit handles from its parent.
-bool LaunchAppAsUser(UserTokenHandle token, const std::wstring& cmdline,
- bool start_hidden, ProcessHandle* process_handle,
- bool empty_desktop_name, bool inherit_handles);
+BASE_API bool LaunchAppAsUser(UserTokenHandle token,
+ const std::wstring& cmdline,
+ bool start_hidden, ProcessHandle* process_handle,
+ bool empty_desktop_name, bool inherit_handles);
#elif defined(OS_POSIX)
@@ -291,14 +297,14 @@ char** AlterEnvironment(const environment_vector& changes,
// Executes the application specified by cl. This function delegates to one
// of the above two platform-specific functions.
-bool LaunchApp(const CommandLine& cl,
- bool wait, bool start_hidden, ProcessHandle* process_handle);
+BASE_API bool LaunchApp(const CommandLine& cl, bool wait, bool start_hidden,
+ ProcessHandle* process_handle);
// Executes the application specified by |cl| and wait for it to exit. Stores
// the output (stdout) in |output|. Redirects stderr to /dev/null. Returns true
// on success (application launched and exited cleanly, with exit code
// indicating success).
-bool GetAppOutput(const CommandLine& cl, std::string* output);
+BASE_API bool GetAppOutput(const CommandLine& cl, std::string* output);
#if defined(OS_POSIX)
// A restricted version of |GetAppOutput()| which (a) clears the environment,
@@ -322,22 +328,22 @@ class ProcessFilter {
// Returns the number of processes on the machine that are running from the
// given executable name. If filter is non-null, then only processes selected
// by the filter will be counted.
-int GetProcessCount(const FilePath::StringType& executable_name,
- const ProcessFilter* filter);
+BASE_API int GetProcessCount(const FilePath::StringType& executable_name,
+ const ProcessFilter* filter);
// Attempts to kill all the processes on the current machine that were launched
// from the given executable name, ending them with the given exit code. If
// filter is non-null, then only processes selected by the filter are killed.
// Returns true if all processes were able to be killed off, false if at least
// one couldn't be killed.
-bool KillProcesses(const FilePath::StringType& executable_name, int exit_code,
- const ProcessFilter* filter);
+BASE_API bool KillProcesses(const FilePath::StringType& executable_name,
+ int exit_code, const ProcessFilter* filter);
// Attempts to kill the process identified by the given process
// entry structure, giving it the specified exit code. If |wait| is true, wait
// for the process to be actually terminated before returning.
// Returns true if this is successful, false otherwise.
-bool KillProcess(ProcessHandle process, int exit_code, bool wait);
+BASE_API bool KillProcess(ProcessHandle process, int exit_code, bool wait);
#if defined(OS_POSIX)
// Attempts to kill the process group identified by |process_group_id|. Returns
@@ -346,7 +352,7 @@ bool KillProcessGroup(ProcessHandle process_group_id);
#endif
#if defined(OS_WIN)
-bool KillProcessById(ProcessId process_id, int exit_code, bool wait);
+BASE_API bool KillProcessById(ProcessId process_id, int exit_code, bool wait);
#endif
// Get the termination status of the process by interpreting the
@@ -357,38 +363,38 @@ bool KillProcessById(ProcessId process_id, int exit_code, bool wait);
// will only return a useful result the first time it is called after
// the child exits (because it will reap the child and the information
// will no longer be available).
-TerminationStatus GetTerminationStatus(ProcessHandle handle, int* exit_code);
+BASE_API TerminationStatus GetTerminationStatus(ProcessHandle handle,
+ int* exit_code);
// Waits for process to exit. On POSIX systems, if the process hasn't been
// signaled then puts the exit code in |exit_code|; otherwise it's considered
// a failure. On Windows |exit_code| is always filled. Returns true on success,
// and closes |handle| in any case.
-bool WaitForExitCode(ProcessHandle handle, int* exit_code);
+BASE_API bool WaitForExitCode(ProcessHandle handle, int* exit_code);
// Waits for process to exit. If it did exit within |timeout_milliseconds|,
-// then puts the exit code in |exit_code|, closes |handle|, and returns true.
+// then puts the exit code in |exit_code|, and returns true.
// In POSIX systems, if the process has been signaled then |exit_code| is set
// to -1. Returns false on failure (the caller is then responsible for closing
// |handle|).
-bool WaitForExitCodeWithTimeout(ProcessHandle handle, int* exit_code,
- int64 timeout_milliseconds);
+// The caller is always responsible for closing the |handle|.
+BASE_API bool WaitForExitCodeWithTimeout(ProcessHandle handle, int* exit_code,
+ int64 timeout_milliseconds);
// Wait for all the processes based on the named executable to exit. If filter
// is non-null, then only processes selected by the filter are waited on.
// Returns after all processes have exited or wait_milliseconds have expired.
// Returns true if all the processes exited, false otherwise.
-bool WaitForProcessesToExit(const FilePath::StringType& executable_name,
- int64 wait_milliseconds,
- const ProcessFilter* filter);
+BASE_API bool WaitForProcessesToExit(
+ const FilePath::StringType& executable_name,
+ int64 wait_milliseconds,
+ const ProcessFilter* filter);
// Wait for a single process to exit. Return true if it exited cleanly within
// the given time limit. On Linux |handle| must be a child process, however
// on Mac and Windows it can be any process.
-bool WaitForSingleProcess(ProcessHandle handle, int64 wait_milliseconds);
-
-// Returns true when |wait_milliseconds| have elapsed and the process
-// is still running.
-bool CrashAwareSleep(ProcessHandle handle, int64 wait_milliseconds);
+BASE_API bool WaitForSingleProcess(ProcessHandle handle,
+ int64 wait_milliseconds);
// Waits a certain amount of time (can be 0) for all the processes with a given
// executable name to exit, then kills off any of them that are still around.
@@ -396,16 +402,16 @@ bool CrashAwareSleep(ProcessHandle handle, int64 wait_milliseconds);
// on. Killed processes are ended with the given exit code. Returns false if
// any processes needed to be killed, true if they all exited cleanly within
// the wait_milliseconds delay.
-bool CleanupProcesses(const FilePath::StringType& executable_name,
- int64 wait_milliseconds,
- int exit_code,
- const ProcessFilter* filter);
+BASE_API bool CleanupProcesses(const FilePath::StringType& executable_name,
+ int64 wait_milliseconds,
+ int exit_code,
+ const ProcessFilter* filter);
// This class provides a way to iterate through a list of processes on the
// current machine with a specified filter.
// To use, create an instance and then call NextProcessEntry() until it returns
// false.
-class ProcessIterator {
+class BASE_API ProcessIterator {
public:
typedef std::list<ProcessEntry> ProcessEntries;
@@ -455,7 +461,7 @@ class ProcessIterator {
// on the current machine that were started from the given executable
// name. To use, create an instance and then call NextProcessEntry()
// until it returns false.
-class NamedProcessIterator : public ProcessIterator {
+class BASE_API NamedProcessIterator : public ProcessIterator {
public:
NamedProcessIterator(const FilePath::StringType& executable_name,
const ProcessFilter* filter);
@@ -520,13 +526,13 @@ struct FreeMBytes {
};
// Convert a POSIX timeval to microseconds.
-int64 TimeValToMicroseconds(const struct timeval& tv);
+BASE_API int64 TimeValToMicroseconds(const struct timeval& tv);
// Provides performance metrics for a specified process (CPU usage, memory and
// IO counters). To use it, invoke CreateProcessMetrics() to get an instance
// for a specific process, then access the information with the different get
// methods.
-class ProcessMetrics {
+class BASE_API ProcessMetrics {
public:
~ProcessMetrics();
@@ -627,7 +633,7 @@ class ProcessMetrics {
// Returns the memory commited by the system in KBytes.
// Returns 0 if it can't compute the commit charge.
-size_t GetSystemCommitCharge();
+BASE_API size_t GetSystemCommitCharge();
// Enables low fragmentation heap (LFH) for every heaps of this process. This
// won't have any effect on heaps created after this function call. It will not
@@ -635,11 +641,11 @@ size_t GetSystemCommitCharge();
// better to call this function early in initialization and again before
// entering the main loop.
// Note: Returns true on Windows 2000 without doing anything.
-bool EnableLowFragmentationHeap();
+BASE_API bool EnableLowFragmentationHeap();
// Enables 'terminate on heap corruption' flag. Helps protect against heap
// overflow. Has no effect if the OS doesn't provide the necessary facility.
-void EnableTerminationOnHeapCorruption();
+BASE_API void EnableTerminationOnHeapCorruption();
#if !defined(OS_WIN)
// Turns on process termination if memory runs out. This is handled on Windows
@@ -651,16 +657,14 @@ malloc_zone_t* GetPurgeableZone();
#endif
#endif
-#if defined(UNIT_TEST)
// Enables stack dump to console output on exception and signals.
// When enabled, the process will quit immediately. This is meant to be used in
// unit_tests only!
-bool EnableInProcessStackDumping();
-#endif // defined(UNIT_TEST)
+BASE_API bool EnableInProcessStackDumping();
// If supported on the platform, and the user has sufficent rights, increase
// the current process's scheduling priority to a high priority.
-void RaiseProcessToHighPriority();
+BASE_API void RaiseProcessToHighPriority();
#if defined(OS_MACOSX)
// Restore the default exception handler, setting it to Apple Crash Reporter
diff --git a/base/process_util_mac.mm b/base/process_util_mac.mm
index 39eabac..e2df2ca 100644
--- a/base/process_util_mac.mm
+++ b/base/process_util_mac.mm
@@ -1,4 +1,4 @@
-// Copyright (c) 2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -622,7 +622,33 @@ void oom_killer_new() {
// === Core Foundation CFAllocators ===
-typedef ChromeCFAllocator* ChromeCFAllocatorRef;
+bool CanGetContextForCFAllocator(long darwin_version) {
+ // TODO(avi): remove at final release; http://crbug.com/74589
+ if (darwin_version == 11) {
+ NSLog(@"Unsure about the internals of CFAllocator but going to patch them "
+ "anyway. Watch out for crashes inside of CFAllocatorAllocate.");
+ }
+ return darwin_version == 9 ||
+ darwin_version == 10 ||
+ darwin_version == 11;
+}
+
+CFAllocatorContext* ContextForCFAllocator(CFAllocatorRef allocator,
+ long darwin_version) {
+ if (darwin_version == 9 || darwin_version == 10) {
+ ChromeCFAllocator9and10* our_allocator =
+ const_cast<ChromeCFAllocator9and10*>(
+ reinterpret_cast<const ChromeCFAllocator9and10*>(allocator));
+ return &our_allocator->_context;
+ } else if (darwin_version == 11) {
+ ChromeCFAllocator11* our_allocator =
+ const_cast<ChromeCFAllocator11*>(
+ reinterpret_cast<const ChromeCFAllocator11*>(allocator));
+ return &our_allocator->_context;
+ } else {
+ return NULL;
+ }
+}
CFAllocatorAllocateCallBack g_old_cfallocator_system_default;
CFAllocatorAllocateCallBack g_old_cfallocator_malloc;
@@ -833,29 +859,30 @@ void EnableTerminationOnOutOfMemory() {
<< "Old allocators unexpectedly non-null";
bool cf_allocator_internals_known =
- darwin_version == 9 || darwin_version == 10;
+ CanGetContextForCFAllocator(darwin_version);
if (cf_allocator_internals_known) {
- ChromeCFAllocatorRef allocator = const_cast<ChromeCFAllocatorRef>(
- reinterpret_cast<const ChromeCFAllocator*>(kCFAllocatorSystemDefault));
- g_old_cfallocator_system_default = allocator->_context.allocate;
+ CFAllocatorContext* context =
+ ContextForCFAllocator(kCFAllocatorSystemDefault, darwin_version);
+ CHECK(context) << "Failed to get context for kCFAllocatorSystemDefault.";
+ g_old_cfallocator_system_default = context->allocate;
CHECK(g_old_cfallocator_system_default)
<< "Failed to get kCFAllocatorSystemDefault allocation function.";
- allocator->_context.allocate = oom_killer_cfallocator_system_default;
+ context->allocate = oom_killer_cfallocator_system_default;
- allocator = const_cast<ChromeCFAllocatorRef>(
- reinterpret_cast<const ChromeCFAllocator*>(kCFAllocatorMalloc));
- g_old_cfallocator_malloc = allocator->_context.allocate;
+ context = ContextForCFAllocator(kCFAllocatorMalloc, darwin_version);
+ CHECK(context) << "Failed to get context for kCFAllocatorMalloc.";
+ g_old_cfallocator_malloc = context->allocate;
CHECK(g_old_cfallocator_malloc)
<< "Failed to get kCFAllocatorMalloc allocation function.";
- allocator->_context.allocate = oom_killer_cfallocator_malloc;
+ context->allocate = oom_killer_cfallocator_malloc;
- allocator = const_cast<ChromeCFAllocatorRef>(
- reinterpret_cast<const ChromeCFAllocator*>(kCFAllocatorMallocZone));
- g_old_cfallocator_malloc_zone = allocator->_context.allocate;
+ context = ContextForCFAllocator(kCFAllocatorMallocZone, darwin_version);
+ CHECK(context) << "Failed to get context for kCFAllocatorMallocZone.";
+ g_old_cfallocator_malloc_zone = context->allocate;
CHECK(g_old_cfallocator_malloc_zone)
<< "Failed to get kCFAllocatorMallocZone allocation function.";
- allocator->_context.allocate = oom_killer_cfallocator_malloc_zone;
+ context->allocate = oom_killer_cfallocator_malloc_zone;
} else {
NSLog(@"Internals of CFAllocator not known; out-of-memory failures via "
"CFAllocator will not result in termination. http://crbug.com/45650");
diff --git a/base/process_util_posix.cc b/base/process_util_posix.cc
index ce56625..47f04a9 100644
--- a/base/process_util_posix.cc
+++ b/base/process_util_posix.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -21,9 +21,10 @@
#include "base/debug/stack_trace.h"
#include "base/dir_reader_posix.h"
#include "base/eintr_wrapper.h"
+#include "base/file_util.h"
#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
#include "base/process_util.h"
-#include "base/scoped_ptr.h"
#include "base/stringprintf.h"
#include "base/synchronization/waitable_event.h"
#include "base/threading/platform_thread.h"
@@ -160,10 +161,17 @@ void StackDumpSignalHandler(int signal, siginfo_t* info, ucontext_t* context) {
void ResetChildSignalHandlersToDefaults() {
// The previous signal handlers are likely to be meaningless in the child's
// context so we reset them to the defaults for now. http://crbug.com/44953
- // These signal handlers are setup in browser_main.cc:BrowserMain
- signal(SIGTERM, SIG_DFL);
+ // These signal handlers are set up at least in browser_main.cc:BrowserMain
+ // and process_util_posix.cc:EnableInProcessStackDumping.
signal(SIGHUP, SIG_DFL);
signal(SIGINT, SIG_DFL);
+ signal(SIGILL, SIG_DFL);
+ signal(SIGABRT, SIG_DFL);
+ signal(SIGFPE, SIG_DFL);
+ signal(SIGBUS, SIG_DFL);
+ signal(SIGSEGV, SIG_DFL);
+ signal(SIGSYS, SIG_DFL);
+ signal(SIGTERM, SIG_DFL);
}
} // anonymous namespace
@@ -300,7 +308,7 @@ void CloseSuperfluousFds(const base::InjectiveMultimap& saved_mapping) {
if (getrlimit(RLIMIT_NOFILE, &nofile)) {
// getrlimit failed. Take a best guess.
max_fds = kSystemDefaultMaxFds;
- DLOG(ERROR) << "getrlimit(RLIMIT_NOFILE) failed: " << errno;
+ RAW_LOG(ERROR, "getrlimit(RLIMIT_NOFILE) failed");
} else {
max_fds = nofile.rlim_cur;
}
@@ -326,7 +334,7 @@ void CloseSuperfluousFds(const base::InjectiveMultimap& saved_mapping) {
// Since we're just trying to close anything we can find,
// ignore any error return values of close().
- int unused ALLOW_UNUSED = HANDLE_EINTR(close(fd));
+ ignore_result(HANDLE_EINTR(close(fd)));
}
return;
}
@@ -509,12 +517,34 @@ bool LaunchAppImpl(
if (pid == 0) {
// Child process
+ // DANGER: fork() rule: in the child, if you don't end up doing exec*(),
+ // you call _exit() instead of exit(). This is because _exit() does not
+ // call any previously-registered (in the parent) exit handlers, which
+ // might do things like block waiting for threads that don't even exist
+ // in the child.
+
+ // If a child process uses the readline library, the process block forever.
+ // In BSD like OSes including OS X it is safe to assign /dev/null as stdin.
+ // See http://crbug.com/56596.
+ int null_fd = HANDLE_EINTR(open("/dev/null", O_RDONLY));
+ if (null_fd < 0) {
+ RAW_LOG(ERROR, "Failed to open /dev/null");
+ _exit(127);
+ }
+
+ file_util::ScopedFD null_fd_closer(&null_fd);
+ int new_fd = HANDLE_EINTR(dup2(null_fd, STDIN_FILENO));
+ if (new_fd != STDIN_FILENO) {
+ RAW_LOG(ERROR, "Failed to dup /dev/null for stdin");
+ _exit(127);
+ }
+
if (start_new_process_group) {
// Instead of inheriting the process group ID of the parent, the child
// starts off a new process group with pgid equal to its process ID.
if (setpgid(0, 0) < 0) {
- PLOG(ERROR) << "setpgid";
- return false;
+ RAW_LOG(ERROR, "setpgid failed");
+ _exit(127);
}
}
#if defined(OS_MACOSX)
@@ -543,12 +573,6 @@ bool LaunchAppImpl(
environ = new_environ.get();
- // Obscure fork() rule: in the child, if you don't end up doing exec*(),
- // you call _exit() instead of exit(). This is because _exit() does not
- // call any previously-registered (in the parent) exit handlers, which
- // might do things like block waiting for threads that don't even exist
- // in the child.
-
// fd_shuffle1 is mutated by this call because it cannot malloc.
if (!ShuffleFileDescriptors(&fd_shuffle1))
_exit(127);
@@ -712,14 +736,15 @@ bool WaitForExitCodeWithTimeout(ProcessHandle handle, int* exit_code,
return false;
if (!waitpid_success)
return false;
- if (!WIFEXITED(status))
- return false;
if (WIFSIGNALED(status)) {
*exit_code = -1;
return true;
}
- *exit_code = WEXITSTATUS(status);
- return true;
+ if (WIFEXITED(status)) {
+ *exit_code = WEXITSTATUS(status);
+ return true;
+ }
+ return false;
}
#if defined(OS_MACOSX)
@@ -809,19 +834,6 @@ bool WaitForSingleProcess(ProcessHandle handle, int64 wait_milliseconds) {
}
}
-bool CrashAwareSleep(ProcessHandle handle, int64 wait_milliseconds) {
- bool waitpid_success;
- int status = WaitpidWithTimeout(handle, wait_milliseconds, &waitpid_success);
- if (status != -1) {
- DCHECK(waitpid_success);
- return !(WIFEXITED(status) || WIFSIGNALED(status));
- } else {
- // If waitpid returned with an error, then the process doesn't exist
- // (which most probably means it didn't exist before our call).
- return waitpid_success;
- }
-}
-
int64 TimeValToMicroseconds(const struct timeval& tv) {
static const int kMicrosecondsPerSecond = 1000000;
int64 ret = tv.tv_sec; // Avoid (int * int) integer overflow.
diff --git a/base/process_util_unittest.cc b/base/process_util_unittest.cc
index 31e1dec..7082408 100644
--- a/base/process_util_unittest.cc
+++ b/base/process_util_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -10,9 +10,9 @@
#include "base/eintr_wrapper.h"
#include "base/file_path.h"
#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
#include "base/path_service.h"
#include "base/process_util.h"
-#include "base/scoped_ptr.h"
#include "base/test/multiprocess_test.h"
#include "base/test/test_timeouts.h"
#include "base/threading/platform_thread.h"
diff --git a/base/process_util_win.cc b/base/process_util_win.cc
index 71f0a1a..a49b78c 100644
--- a/base/process_util_win.cc
+++ b/base/process_util_win.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -15,8 +15,9 @@
#include "base/command_line.h"
#include "base/debug/stack_trace.h"
#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
#include "base/metrics/histogram.h"
-#include "base/scoped_ptr.h"
+#include "base/sys_info.h"
#include "base/win/scoped_handle.h"
#include "base/win/windows_version.h"
@@ -464,8 +465,7 @@ TerminationStatus GetTerminationStatus(ProcessHandle handle, int* exit_code) {
bool WaitForExitCode(ProcessHandle handle, int* exit_code) {
bool success = WaitForExitCodeWithTimeout(handle, exit_code, INFINITE);
- if (!success)
- CloseProcessHandle(handle);
+ CloseProcessHandle(handle);
return success;
}
@@ -477,10 +477,6 @@ bool WaitForExitCodeWithTimeout(ProcessHandle handle, int* exit_code,
if (!::GetExitCodeProcess(handle, &temp_code))
return false;
- // Only close the handle on success, to give the caller a chance to forcefully
- // terminate the process if he wants to.
- CloseProcessHandle(handle);
-
*exit_code = temp_code;
return true;
}
@@ -544,11 +540,6 @@ bool WaitForSingleProcess(ProcessHandle handle, int64 wait_milliseconds) {
return retval;
}
-bool CrashAwareSleep(ProcessHandle handle, int64 wait_milliseconds) {
- bool retval = WaitForSingleObject(handle, wait_milliseconds) == WAIT_TIMEOUT;
- return retval;
-}
-
bool CleanupProcesses(const std::wstring& executable_name,
int64 wait_milliseconds,
int exit_code,
@@ -564,12 +555,11 @@ bool CleanupProcesses(const std::wstring& executable_name,
///////////////////////////////////////////////////////////////////////////////
// ProcesMetrics
-ProcessMetrics::ProcessMetrics(ProcessHandle process) : process_(process),
- last_time_(0),
- last_system_time_(0) {
- SYSTEM_INFO system_info;
- GetSystemInfo(&system_info);
- processor_count_ = system_info.dwNumberOfProcessors;
+ProcessMetrics::ProcessMetrics(ProcessHandle process)
+ : process_(process),
+ processor_count_(base::SysInfo::NumberOfProcessors()),
+ last_time_(0),
+ last_system_time_(0) {
}
// static
diff --git a/base/process_win.cc b/base/process_win.cc
index cdb9390..2873d91 100644
--- a/base/process_win.cc
+++ b/base/process_win.cc
@@ -1,11 +1,11 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
#include "base/process.h"
#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
#include "base/process_util.h"
-#include "base/scoped_ptr.h"
namespace base {
diff --git a/base/rand_util.cc b/base/rand_util.cc
index 0576c94..4a455f1 100644
--- a/base/rand_util.cc
+++ b/base/rand_util.cc
@@ -37,7 +37,7 @@ double RandDouble() {
}
uint64 RandGenerator(uint64 max) {
- DCHECK(max > 0);
+ DCHECK_GT(max, 0ULL);
return base::RandUint64() % max;
}
diff --git a/base/rand_util.h b/base/rand_util.h
index 699fc7f..a4ea479 100644
--- a/base/rand_util.h
+++ b/base/rand_util.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -6,25 +6,26 @@
#define BASE_RAND_UTIL_H_
#pragma once
+#include "base/base_api.h"
#include "base/basictypes.h"
namespace base {
// Returns a random number in range [0, kuint64max]. Thread-safe.
-uint64 RandUint64();
+BASE_API uint64 RandUint64();
// Returns a random number between min and max (inclusive). Thread-safe.
-int RandInt(int min, int max);
+BASE_API int RandInt(int min, int max);
// Returns a random number in range [0, max). Thread-safe.
//
// Note that this can be used as an adapter for std::random_shuffle():
// Given a pre-populated |std::vector<int> myvector|, shuffle it as
// std::random_shuffle(myvector.begin(), myvector.end(), base::RandGenerator);
-uint64 RandGenerator(uint64 max);
+BASE_API uint64 RandGenerator(uint64 max);
// Returns a random double in range [0, 1). Thread-safe.
-double RandDouble();
+BASE_API double RandDouble();
} // namespace base
diff --git a/base/resource_util.h b/base/resource_util.h
index 8a37f95..c867abc 100644
--- a/base/resource_util.h
+++ b/base/resource_util.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -11,6 +11,7 @@
#include <windows.h>
+#include "base/base_api.h"
#include "base/basictypes.h"
namespace base {
@@ -18,8 +19,8 @@ namespace base {
// Function for getting a data resource (BINDATA) from a dll. Some
// resources are optional, especially in unit tests, so this returns false
// but doesn't raise an error if the resource can't be loaded.
-bool GetDataResourceFromModule(HMODULE module, int resource_id,
- void** data, size_t* length);
+bool BASE_API GetDataResourceFromModule(HMODULE module, int resource_id,
+ void** data, size_t* length);
} // namespace base
#endif // BASE_RESOURCE_UTIL_H__
diff --git a/base/scoped_comptr_win.h b/base/scoped_comptr_win.h
deleted file mode 100644
index 7f15885..0000000
--- a/base/scoped_comptr_win.h
+++ /dev/null
@@ -1,9 +0,0 @@
-// 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.
-
-// TODO(brettw) remove this file when all callers are converted to using the
-// new location/namespace
-#include "base/win/scoped_comptr.h"
-
-using base::win::ScopedComPtr;
diff --git a/base/scoped_ptr.h b/base/scoped_ptr.h
index 0a90150..f36da51 100644
--- a/base/scoped_ptr.h
+++ b/base/scoped_ptr.h
@@ -1,383 +1,13 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
-// Scopers help you manage ownership of a pointer, helping you easily manage the
-// a pointer within a scope, and automatically destroying the pointer at the
-// end of a scope. There are two main classes you will use, which correspond
-// to the operators new/delete and new[]/delete[].
-//
-// Example usage (scoped_ptr):
-// {
-// scoped_ptr<Foo> foo(new Foo("wee"));
-// } // foo goes out of scope, releasing the pointer with it.
-//
-// {
-// scoped_ptr<Foo> foo; // No pointer managed.
-// foo.reset(new Foo("wee")); // Now a pointer is managed.
-// foo.reset(new Foo("wee2")); // Foo("wee") was destroyed.
-// foo.reset(new Foo("wee3")); // Foo("wee2") was destroyed.
-// foo->Method(); // Foo::Method() called.
-// foo.get()->Method(); // Foo::Method() called.
-// SomeFunc(foo.release()); // SomeFunc takes ownership, foo no longer
-// // manages a pointer.
-// foo.reset(new Foo("wee4")); // foo manages a pointer again.
-// foo.reset(); // Foo("wee4") destroyed, foo no longer
-// // manages a pointer.
-// } // foo wasn't managing a pointer, so nothing was destroyed.
-//
-// Example usage (scoped_array):
-// {
-// scoped_array<Foo> foo(new Foo[100]);
-// foo.get()->Method(); // Foo::Method on the 0th element.
-// foo[10].Method(); // Foo::Method on the 10th element.
-// }
-
#ifndef BASE_SCOPED_PTR_H_
#define BASE_SCOPED_PTR_H_
#pragma once
-// This is an implementation designed to match the anticipated future TR2
-// implementation of the scoped_ptr class, and its closely-related brethren,
-// scoped_array, scoped_ptr_malloc.
-
-#include <assert.h>
-#include <stddef.h>
-#include <stdlib.h>
-
-#include "base/compiler_specific.h"
-
-// A scoped_ptr<T> is like a T*, except that the destructor of scoped_ptr<T>
-// automatically deletes the pointer it holds (if any).
-// That is, scoped_ptr<T> owns the T object that it points to.
-// Like a T*, a scoped_ptr<T> may hold either NULL or a pointer to a T object.
-// Also like T*, scoped_ptr<T> is thread-compatible, and once you
-// dereference it, you get the threadsafety guarantees of T.
-//
-// The size of a scoped_ptr is small:
-// sizeof(scoped_ptr<C>) == sizeof(C*)
-template <class C>
-class scoped_ptr {
- public:
-
- // The element type
- typedef C element_type;
-
- // Constructor. Defaults to initializing with NULL.
- // There is no way to create an uninitialized scoped_ptr.
- // The input parameter must be allocated with new.
- explicit scoped_ptr(C* p = NULL) : ptr_(p) { }
-
- // Destructor. If there is a C object, delete it.
- // We don't need to test ptr_ == NULL because C++ does that for us.
- ~scoped_ptr() {
- enum { type_must_be_complete = sizeof(C) };
- delete ptr_;
- }
-
- // Reset. Deletes the current owned object, if any.
- // Then takes ownership of a new object, if given.
- // this->reset(this->get()) works.
- void reset(C* p = NULL) {
- if (p != ptr_) {
- enum { type_must_be_complete = sizeof(C) };
- delete ptr_;
- ptr_ = p;
- }
- }
-
- // Accessors to get the owned object.
- // operator* and operator-> will assert() if there is no current object.
- C& operator*() const {
- assert(ptr_ != NULL);
- return *ptr_;
- }
- C* operator->() const {
- assert(ptr_ != NULL);
- return ptr_;
- }
- C* get() const { return ptr_; }
-
- // Comparison operators.
- // These return whether two scoped_ptr refer to the same object, not just to
- // two different but equal objects.
- bool operator==(C* p) const { return ptr_ == p; }
- bool operator!=(C* p) const { return ptr_ != p; }
-
- // Swap two scoped pointers.
- void swap(scoped_ptr& p2) {
- C* tmp = ptr_;
- ptr_ = p2.ptr_;
- p2.ptr_ = tmp;
- }
-
- // Release a pointer.
- // The return value is the current pointer held by this object.
- // If this object holds a NULL pointer, the return value is NULL.
- // After this operation, this object will hold a NULL pointer,
- // and will not own the object any more.
- C* release() WARN_UNUSED_RESULT {
- C* retVal = ptr_;
- ptr_ = NULL;
- return retVal;
- }
-
- private:
- C* ptr_;
-
- // Forbid comparison of scoped_ptr types. If C2 != C, it totally doesn't
- // make sense, and if C2 == C, it still doesn't make sense because you should
- // never have the same object owned by two different scoped_ptrs.
- template <class C2> bool operator==(scoped_ptr<C2> const& p2) const;
- template <class C2> bool operator!=(scoped_ptr<C2> const& p2) const;
-
- // Disallow evil constructors
- scoped_ptr(const scoped_ptr&);
- void operator=(const scoped_ptr&);
-};
-
-// Free functions
-template <class C>
-void swap(scoped_ptr<C>& p1, scoped_ptr<C>& p2) {
- p1.swap(p2);
-}
-
-template <class C>
-bool operator==(C* p1, const scoped_ptr<C>& p2) {
- return p1 == p2.get();
-}
-
-template <class C>
-bool operator!=(C* p1, const scoped_ptr<C>& p2) {
- return p1 != p2.get();
-}
-
-// scoped_array<C> is like scoped_ptr<C>, except that the caller must allocate
-// with new [] and the destructor deletes objects with delete [].
-//
-// As with scoped_ptr<C>, a scoped_array<C> either points to an object
-// or is NULL. A scoped_array<C> owns the object that it points to.
-// scoped_array<T> is thread-compatible, and once you index into it,
-// the returned objects have only the threadsafety guarantees of T.
-//
-// Size: sizeof(scoped_array<C>) == sizeof(C*)
-template <class C>
-class scoped_array {
- public:
-
- // The element type
- typedef C element_type;
-
- // Constructor. Defaults to intializing with NULL.
- // There is no way to create an uninitialized scoped_array.
- // The input parameter must be allocated with new [].
- explicit scoped_array(C* p = NULL) : array_(p) { }
-
- // Destructor. If there is a C object, delete it.
- // We don't need to test ptr_ == NULL because C++ does that for us.
- ~scoped_array() {
- enum { type_must_be_complete = sizeof(C) };
- delete[] array_;
- }
-
- // Reset. Deletes the current owned object, if any.
- // Then takes ownership of a new object, if given.
- // this->reset(this->get()) works.
- void reset(C* p = NULL) {
- if (p != array_) {
- enum { type_must_be_complete = sizeof(C) };
- delete[] array_;
- array_ = p;
- }
- }
-
- // Get one element of the current object.
- // Will assert() if there is no current object, or index i is negative.
- C& operator[](ptrdiff_t i) const {
- assert(i >= 0);
- assert(array_ != NULL);
- return array_[i];
- }
-
- // Get a pointer to the zeroth element of the current object.
- // If there is no current object, return NULL.
- C* get() const {
- return array_;
- }
-
- // Comparison operators.
- // These return whether two scoped_array refer to the same object, not just to
- // two different but equal objects.
- bool operator==(C* p) const { return array_ == p; }
- bool operator!=(C* p) const { return array_ != p; }
-
- // Swap two scoped arrays.
- void swap(scoped_array& p2) {
- C* tmp = array_;
- array_ = p2.array_;
- p2.array_ = tmp;
- }
-
- // Release an array.
- // The return value is the current pointer held by this object.
- // If this object holds a NULL pointer, the return value is NULL.
- // After this operation, this object will hold a NULL pointer,
- // and will not own the object any more.
- C* release() WARN_UNUSED_RESULT {
- C* retVal = array_;
- array_ = NULL;
- return retVal;
- }
-
- private:
- C* array_;
-
- // Forbid comparison of different scoped_array types.
- template <class C2> bool operator==(scoped_array<C2> const& p2) const;
- template <class C2> bool operator!=(scoped_array<C2> const& p2) const;
-
- // Disallow evil constructors
- scoped_array(const scoped_array&);
- void operator=(const scoped_array&);
-};
-
-// Free functions
-template <class C>
-void swap(scoped_array<C>& p1, scoped_array<C>& p2) {
- p1.swap(p2);
-}
-
-template <class C>
-bool operator==(C* p1, const scoped_array<C>& p2) {
- return p1 == p2.get();
-}
-
-template <class C>
-bool operator!=(C* p1, const scoped_array<C>& p2) {
- return p1 != p2.get();
-}
-
-// This class wraps the c library function free() in a class that can be
-// passed as a template argument to scoped_ptr_malloc below.
-class ScopedPtrMallocFree {
- public:
- inline void operator()(void* x) const {
- free(x);
- }
-};
-
-// scoped_ptr_malloc<> is similar to scoped_ptr<>, but it accepts a
-// second template argument, the functor used to free the object.
-
-template<class C, class FreeProc = ScopedPtrMallocFree>
-class scoped_ptr_malloc {
- public:
-
- // The element type
- typedef C element_type;
-
- // Constructor. Defaults to initializing with NULL.
- // There is no way to create an uninitialized scoped_ptr.
- // The input parameter must be allocated with an allocator that matches the
- // Free functor. For the default Free functor, this is malloc, calloc, or
- // realloc.
- explicit scoped_ptr_malloc(C* p = NULL): ptr_(p) {}
-
- // Destructor. If there is a C object, call the Free functor.
- ~scoped_ptr_malloc() {
- free_(ptr_);
- }
-
- // Reset. Calls the Free functor on the current owned object, if any.
- // Then takes ownership of a new object, if given.
- // this->reset(this->get()) works.
- void reset(C* p = NULL) {
- if (ptr_ != p) {
- free_(ptr_);
- ptr_ = p;
- }
- }
-
- // Get the current object.
- // operator* and operator-> will cause an assert() failure if there is
- // no current object.
- C& operator*() const {
- assert(ptr_ != NULL);
- return *ptr_;
- }
-
- C* operator->() const {
- assert(ptr_ != NULL);
- return ptr_;
- }
-
- C* get() const {
- return ptr_;
- }
-
- // Comparison operators.
- // These return whether a scoped_ptr_malloc and a plain pointer refer
- // to the same object, not just to two different but equal objects.
- // For compatibility with the boost-derived implementation, these
- // take non-const arguments.
- bool operator==(C* p) const {
- return ptr_ == p;
- }
-
- bool operator!=(C* p) const {
- return ptr_ != p;
- }
-
- // Swap two scoped pointers.
- void swap(scoped_ptr_malloc & b) {
- C* tmp = b.ptr_;
- b.ptr_ = ptr_;
- ptr_ = tmp;
- }
-
- // Release a pointer.
- // The return value is the current pointer held by this object.
- // If this object holds a NULL pointer, the return value is NULL.
- // After this operation, this object will hold a NULL pointer,
- // and will not own the object any more.
- C* release() WARN_UNUSED_RESULT {
- C* tmp = ptr_;
- ptr_ = NULL;
- return tmp;
- }
-
- private:
- C* ptr_;
-
- // no reason to use these: each scoped_ptr_malloc should have its own object
- template <class C2, class GP>
- bool operator==(scoped_ptr_malloc<C2, GP> const& p) const;
- template <class C2, class GP>
- bool operator!=(scoped_ptr_malloc<C2, GP> const& p) const;
-
- static FreeProc const free_;
-
- // Disallow evil constructors
- scoped_ptr_malloc(const scoped_ptr_malloc&);
- void operator=(const scoped_ptr_malloc&);
-};
-
-template<class C, class FP>
-FP const scoped_ptr_malloc<C, FP>::free_ = FP();
-
-template<class C, class FP> inline
-void swap(scoped_ptr_malloc<C, FP>& a, scoped_ptr_malloc<C, FP>& b) {
- a.swap(b);
-}
-
-template<class C, class FP> inline
-bool operator==(C* p, const scoped_ptr_malloc<C, FP>& b) {
- return p == b.get();
-}
-
-template<class C, class FP> inline
-bool operator!=(C* p, const scoped_ptr_malloc<C, FP>& b) {
- return p != b.get();
-}
+// FIXME: Remove this header when third_party/cacheinvalidation is fixed to not
+// rely on it.
+#include "base/memory/scoped_ptr.h"
#endif // BASE_SCOPED_PTR_H_
diff --git a/base/sha1.h b/base/sha1.h
index dd43686..7625189 100644
--- a/base/sha1.h
+++ b/base/sha1.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -8,6 +8,8 @@
#include <string>
+#include "base/base_api.h"
+
namespace base {
// This function performs SHA-1 operations.
@@ -18,7 +20,12 @@ enum {
// Computes the SHA-1 hash of the input string |str| and returns the full
// hash.
-std::string SHA1HashString(const std::string& str);
+BASE_API std::string SHA1HashString(const std::string& str);
+
+// Computes the SHA-1 hash of the |len| bytes in |data| and puts the hash
+// in |hash|. |hash| must be SHA1_LENGTH bytes long.
+BASE_API void SHA1HashBytes(const unsigned char* data, size_t len,
+ unsigned char* hash);
} // namespace base
diff --git a/base/sha1_portable.cc b/base/sha1_portable.cc
index cc05a5c..529fc90 100644
--- a/base/sha1_portable.cc
+++ b/base/sha1_portable.cc
@@ -4,6 +4,8 @@
#include "base/sha1.h"
+#include <string.h>
+
#include "base/basictypes.h"
namespace base {
@@ -195,12 +197,19 @@ void SecureHashAlgorithm::Process() {
}
std::string SHA1HashString(const std::string& str) {
+ char hash[SecureHashAlgorithm::kDigestSizeBytes];
+ SHA1HashBytes(reinterpret_cast<const unsigned char*>(str.c_str()),
+ str.length(), reinterpret_cast<unsigned char*>(hash));
+ return std::string(hash, SecureHashAlgorithm::kDigestSizeBytes);
+}
+
+void SHA1HashBytes(const unsigned char* data, size_t len,
+ unsigned char* hash) {
SecureHashAlgorithm sha;
- sha.Update(str.c_str(), str.length());
+ sha.Update(data, len);
sha.Final();
- std::string out(reinterpret_cast<const char*>(sha.Digest()),
- SecureHashAlgorithm::kDigestSizeBytes);
- return out;
+
+ memcpy(hash, sha.Digest(), SecureHashAlgorithm::kDigestSizeBytes);
}
} // namespace base
diff --git a/base/sha1_unittest.cc b/base/sha1_unittest.cc
index e445e8f..406150b 100644
--- a/base/sha1_unittest.cc
+++ b/base/sha1_unittest.cc
@@ -54,3 +54,55 @@ TEST(SHA1Test, Test3) {
for (size_t i = 0; i < base::SHA1_LENGTH; i++)
EXPECT_EQ(expected[i], output[i] & 0xFF);
}
+
+TEST(SHA1Test, Test1Bytes) {
+ // Example A.1 from FIPS 180-2: one-block message.
+ std::string input = "abc";
+ unsigned char output[base::SHA1_LENGTH];
+
+ unsigned char expected[] = { 0xa9, 0x99, 0x3e, 0x36,
+ 0x47, 0x06, 0x81, 0x6a,
+ 0xba, 0x3e, 0x25, 0x71,
+ 0x78, 0x50, 0xc2, 0x6c,
+ 0x9c, 0xd0, 0xd8, 0x9d };
+
+ base::SHA1HashBytes(reinterpret_cast<const unsigned char*>(input.c_str()),
+ input.length(), output);
+ for (size_t i = 0; i < base::SHA1_LENGTH; i++)
+ EXPECT_EQ(expected[i], output[i]);
+}
+
+TEST(SHA1Test, Test2Bytes) {
+ // Example A.2 from FIPS 180-2: multi-block message.
+ std::string input =
+ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq";
+ unsigned char output[base::SHA1_LENGTH];
+
+ unsigned char expected[] = { 0x84, 0x98, 0x3e, 0x44,
+ 0x1c, 0x3b, 0xd2, 0x6e,
+ 0xba, 0xae, 0x4a, 0xa1,
+ 0xf9, 0x51, 0x29, 0xe5,
+ 0xe5, 0x46, 0x70, 0xf1 };
+
+ base::SHA1HashBytes(reinterpret_cast<const unsigned char*>(input.c_str()),
+ input.length(), output);
+ for (size_t i = 0; i < base::SHA1_LENGTH; i++)
+ EXPECT_EQ(expected[i], output[i]);
+}
+
+TEST(SHA1Test, Test3Bytes) {
+ // Example A.3 from FIPS 180-2: long message.
+ std::string input(1000000, 'a');
+ unsigned char output[base::SHA1_LENGTH];
+
+ unsigned char expected[] = { 0x34, 0xaa, 0x97, 0x3c,
+ 0xd4, 0xc4, 0xda, 0xa4,
+ 0xf6, 0x1e, 0xeb, 0x2b,
+ 0xdb, 0xad, 0x27, 0x31,
+ 0x65, 0x34, 0x01, 0x6f };
+
+ base::SHA1HashBytes(reinterpret_cast<const unsigned char*>(input.c_str()),
+ input.length(), output);
+ for (size_t i = 0; i < base::SHA1_LENGTH; i++)
+ EXPECT_EQ(expected[i], output[i]);
+}
diff --git a/base/sha1_win.cc b/base/sha1_win.cc
index 853c244..233749b 100644
--- a/base/sha1_win.cc
+++ b/base/sha1_win.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -7,7 +7,9 @@
#include <windows.h>
#include <wincrypt.h>
-#include "base/crypto/scoped_capi_types.h"
+// This file is not being compiled at the moment (see bug 47218). If we keep
+// sha1 inside base, we cannot depend on src/crypto.
+// #include "crypto/scoped_capi_types.h"
#include "base/logging.h"
namespace base {
diff --git a/base/sha2.cc b/base/sha2.cc
deleted file mode 100644
index c0fd0ab..0000000
--- a/base/sha2.cc
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright (c) 2006-2008 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.
-
-#include "base/sha2.h"
-
-#include "base/stl_util-inl.h"
-#include "base/third_party/nss/blapi.h"
-#include "base/third_party/nss/sha256.h"
-
-namespace base {
-
-void SHA256HashString(const std::string& str, void* output, size_t len) {
- SHA256Context ctx;
-
- SHA256_Begin(&ctx);
- SHA256_Update(&ctx, reinterpret_cast<const unsigned char*>(str.data()),
- static_cast<unsigned int>(str.length()));
- SHA256_End(&ctx, static_cast<unsigned char*>(output), NULL,
- static_cast<unsigned int>(len));
-}
-
-std::string SHA256HashString(const std::string& str) {
- std::string output(SHA256_LENGTH, 0);
- SHA256HashString(str, string_as_array(&output), output.size());
- return output;
-}
-
-} // namespace base
diff --git a/base/sha2.h b/base/sha2.h
deleted file mode 100644
index 19e41c3..0000000
--- a/base/sha2.h
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright (c) 2006-2008 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 BASE_SHA2_H_
-#define BASE_SHA2_H_
-#pragma once
-
-#include <string>
-
-namespace base {
-
-// These functions perform SHA-256 operations.
-//
-// Functions for SHA-384 and SHA-512 can be added when the need arises.
-
-enum {
- SHA256_LENGTH = 32 // length in bytes of a SHA-256 hash
-};
-
-// Computes the SHA-256 hash of the input string 'str' and stores the first
-// 'len' bytes of the hash in the output buffer 'output'. If 'len' > 32,
-// only 32 bytes (the full hash) are stored in the 'output' buffer.
-void SHA256HashString(const std::string& str, void* output, size_t len);
-
-// Convenience version of the above that returns the result in a 32-byte
-// string.
-std::string SHA256HashString(const std::string& str);
-
-} // namespace base
-
-#endif // BASE_SHA2_H_
diff --git a/base/sha2_openssl.cc b/base/sha2_openssl.cc
deleted file mode 100644
index afbce2f..0000000
--- a/base/sha2_openssl.cc
+++ /dev/null
@@ -1,30 +0,0 @@
-// 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.
-
-#include "base/sha2.h"
-
-#include <openssl/ssl.h>
-
-#include "base/basictypes.h"
-#include "base/openssl_util.h"
-#include "base/stl_util-inl.h"
-
-namespace base {
-
-void SHA256HashString(const std::string& str, void* output, size_t len) {
- COMPILE_ASSERT(SHA256_LENGTH == SHA256_DIGEST_LENGTH,
- API_and_OpenSSL_SHA256_lengths_must_match);
- ScopedOpenSSLSafeSizeBuffer<SHA256_DIGEST_LENGTH> result(
- reinterpret_cast<unsigned char*>(output), len);
- ::SHA256(reinterpret_cast<const unsigned char*>(str.data()), str.size(),
- result.safe_buffer());
-}
-
-std::string SHA256HashString(const std::string& str) {
- std::string output(SHA256_LENGTH, 0);
- SHA256HashString(str, string_as_array(&output), output.size());
- return output;
-}
-
-} // namespace base
diff --git a/base/sha2_unittest.cc b/base/sha2_unittest.cc
deleted file mode 100644
index b0321e8..0000000
--- a/base/sha2_unittest.cc
+++ /dev/null
@@ -1,97 +0,0 @@
-// Copyright (c) 2006-2008 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.
-
-#include "base/sha2.h"
-
-#include "base/basictypes.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-TEST(Sha256Test, Test1) {
- // Example B.1 from FIPS 180-2: one-block message.
- std::string input1 = "abc";
- int expected1[] = { 0xba, 0x78, 0x16, 0xbf,
- 0x8f, 0x01, 0xcf, 0xea,
- 0x41, 0x41, 0x40, 0xde,
- 0x5d, 0xae, 0x22, 0x23,
- 0xb0, 0x03, 0x61, 0xa3,
- 0x96, 0x17, 0x7a, 0x9c,
- 0xb4, 0x10, 0xff, 0x61,
- 0xf2, 0x00, 0x15, 0xad };
-
- uint8 output1[base::SHA256_LENGTH];
- base::SHA256HashString(input1, output1, sizeof(output1));
- for (size_t i = 0; i < base::SHA256_LENGTH; i++)
- EXPECT_EQ(expected1[i], static_cast<int>(output1[i]));
-
- uint8 output_truncated1[4]; // 4 bytes == 32 bits
- base::SHA256HashString(input1, output_truncated1, sizeof(output_truncated1));
- for (size_t i = 0; i < sizeof(output_truncated1); i++)
- EXPECT_EQ(expected1[i], static_cast<int>(output_truncated1[i]));
-}
-
-TEST(Sha256Test, Test1_String) {
- // Same as the above, but using the wrapper that returns a std::string.
- // Example B.1 from FIPS 180-2: one-block message.
- std::string input1 = "abc";
- int expected1[] = { 0xba, 0x78, 0x16, 0xbf,
- 0x8f, 0x01, 0xcf, 0xea,
- 0x41, 0x41, 0x40, 0xde,
- 0x5d, 0xae, 0x22, 0x23,
- 0xb0, 0x03, 0x61, 0xa3,
- 0x96, 0x17, 0x7a, 0x9c,
- 0xb4, 0x10, 0xff, 0x61,
- 0xf2, 0x00, 0x15, 0xad };
-
- std::string output1 = base::SHA256HashString(input1);
- ASSERT_EQ(base::SHA256_LENGTH, output1.size());
- for (size_t i = 0; i < base::SHA256_LENGTH; i++)
- EXPECT_EQ(expected1[i], static_cast<uint8>(output1[i]));
-}
-
-TEST(Sha256Test, Test2) {
- // Example B.2 from FIPS 180-2: multi-block message.
- std::string input2 =
- "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq";
- int expected2[] = { 0x24, 0x8d, 0x6a, 0x61,
- 0xd2, 0x06, 0x38, 0xb8,
- 0xe5, 0xc0, 0x26, 0x93,
- 0x0c, 0x3e, 0x60, 0x39,
- 0xa3, 0x3c, 0xe4, 0x59,
- 0x64, 0xff, 0x21, 0x67,
- 0xf6, 0xec, 0xed, 0xd4,
- 0x19, 0xdb, 0x06, 0xc1 };
-
- uint8 output2[base::SHA256_LENGTH];
- base::SHA256HashString(input2, output2, sizeof(output2));
- for (size_t i = 0; i < base::SHA256_LENGTH; i++)
- EXPECT_EQ(expected2[i], static_cast<int>(output2[i]));
-
- uint8 output_truncated2[6];
- base::SHA256HashString(input2, output_truncated2, sizeof(output_truncated2));
- for (size_t i = 0; i < sizeof(output_truncated2); i++)
- EXPECT_EQ(expected2[i], static_cast<int>(output_truncated2[i]));
-}
-
-TEST(Sha256Test, Test3) {
- // Example B.3 from FIPS 180-2: long message.
- std::string input3(1000000, 'a'); // 'a' repeated a million times
- int expected3[] = { 0xcd, 0xc7, 0x6e, 0x5c,
- 0x99, 0x14, 0xfb, 0x92,
- 0x81, 0xa1, 0xc7, 0xe2,
- 0x84, 0xd7, 0x3e, 0x67,
- 0xf1, 0x80, 0x9a, 0x48,
- 0xa4, 0x97, 0x20, 0x0e,
- 0x04, 0x6d, 0x39, 0xcc,
- 0xc7, 0x11, 0x2c, 0xd0 };
-
- uint8 output3[base::SHA256_LENGTH];
- base::SHA256HashString(input3, output3, sizeof(output3));
- for (size_t i = 0; i < base::SHA256_LENGTH; i++)
- EXPECT_EQ(expected3[i], static_cast<int>(output3[i]));
-
- uint8 output_truncated3[12];
- base::SHA256HashString(input3, output_truncated3, sizeof(output_truncated3));
- for (size_t i = 0; i < sizeof(output_truncated3); i++)
- EXPECT_EQ(expected3[i], static_cast<int>(output_truncated3[i]));
-}
diff --git a/base/shared_memory.h b/base/shared_memory.h
index a088682..cf07da3 100644
--- a/base/shared_memory.h
+++ b/base/shared_memory.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -15,6 +15,7 @@
#endif
#include <string>
+#include "base/base_api.h"
#include "base/basictypes.h"
#include "base/process.h"
@@ -39,7 +40,7 @@ typedef ino_t SharedMemoryId;
// Platform abstraction for shared memory. Provides a C++ wrapper
// around the OS primitive for a memory mapped file.
-class SharedMemory {
+class BASE_API SharedMemory {
public:
SharedMemory();
diff --git a/base/shared_memory_posix.cc b/base/shared_memory_posix.cc
index bd2c6e5..682dc5c 100644
--- a/base/shared_memory_posix.cc
+++ b/base/shared_memory_posix.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -142,7 +142,7 @@ bool SharedMemory::CreateNamed(const std::string& name,
return false;
const uint32 current_size = stat.st_size;
if (current_size != size) {
- if (ftruncate(fileno(fp), size) != 0)
+ if (HANDLE_EINTR(ftruncate(fileno(fp), size)) != 0)
return false;
if (fseeko(fp, size, SEEK_SET) != 0)
return false;
@@ -296,8 +296,12 @@ bool SharedMemory::FilePathForMemoryName(const std::string& mem_name,
}
void SharedMemory::LockOrUnlockCommon(int function) {
+<<<<<<< HEAD
DCHECK(mapped_file_ >= 0);
#if !defined(ANDROID)
+=======
+ DCHECK_GE(mapped_file_, 0);
+>>>>>>> chromium.org at r12.0.742.93
while (lockf(mapped_file_, function, 0) < 0) {
if (errno == EINTR) {
continue;
@@ -320,7 +324,7 @@ bool SharedMemory::ShareToProcessCommon(ProcessHandle process,
SharedMemoryHandle *new_handle,
bool close_self) {
const int new_fd = dup(mapped_file_);
- DCHECK(new_fd >= 0);
+ DCHECK_GE(new_fd, 0);
new_handle->fd = new_fd;
new_handle->auto_close = true;
diff --git a/base/shared_memory_unittest.cc b/base/shared_memory_unittest.cc
index b515e79..edcbb50 100644
--- a/base/shared_memory_unittest.cc
+++ b/base/shared_memory_unittest.cc
@@ -1,11 +1,11 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
#include "base/basictypes.h"
#include "base/mac/scoped_nsautorelease_pool.h"
+#include "base/memory/scoped_ptr.h"
#include "base/shared_memory.h"
-#include "base/scoped_ptr.h"
#include "base/test/multiprocess_test.h"
#include "base/threading/platform_thread.h"
#include "base/time.h"
diff --git a/base/stack_container_unittest.cc b/base/stack_container_unittest.cc
index e1392c1..816ee07 100644
--- a/base/stack_container_unittest.cc
+++ b/base/stack_container_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -6,8 +6,8 @@
#include <algorithm>
+#include "base/memory/ref_counted.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "base/ref_counted.h"
namespace {
diff --git a/base/string_number_conversions.h b/base/string_number_conversions.h
index c3d79b6..a4b6e3e 100644
--- a/base/string_number_conversions.h
+++ b/base/string_number_conversions.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -8,6 +8,7 @@
#include <string>
#include <vector>
+#include "base/base_api.h"
#include "base/basictypes.h"
#include "base/string16.h"
@@ -27,21 +28,21 @@ namespace base {
// Number -> string conversions ------------------------------------------------
-std::string IntToString(int value);
-string16 IntToString16(int value);
+BASE_API std::string IntToString(int value);
+BASE_API string16 IntToString16(int value);
-std::string UintToString(unsigned value);
-string16 UintToString16(unsigned value);
+BASE_API std::string UintToString(unsigned value);
+BASE_API string16 UintToString16(unsigned value);
-std::string Int64ToString(int64 value);
-string16 Int64ToString16(int64 value);
+BASE_API std::string Int64ToString(int64 value);
+BASE_API string16 Int64ToString16(int64 value);
-std::string Uint64ToString(uint64 value);
-string16 Uint64ToString16(uint64 value);
+BASE_API std::string Uint64ToString(uint64 value);
+BASE_API string16 Uint64ToString16(uint64 value);
// DoubleToString converts the double to a string format that ignores the
// locale. If you want to use locale specific formatting, use ICU.
-std::string DoubleToString(double value);
+BASE_API std::string DoubleToString(double value);
// String -> number conversions ------------------------------------------------
@@ -57,29 +58,30 @@ std::string DoubleToString(double value);
// - No characters parseable as a number at the beginning of the string.
// |*output| will be set to 0.
// - Empty string. |*output| will be set to 0.
-bool StringToInt(const std::string& input, int* output);
-bool StringToInt(std::string::const_iterator begin,
- std::string::const_iterator end,
- int* output);
-bool StringToInt(const char* begin, const char* end, int* output);
-
-bool StringToInt(const string16& input, int* output);
-bool StringToInt(string16::const_iterator begin,
- string16::const_iterator end,
- int* output);
-bool StringToInt(const char16* begin, const char16* end, int* output);
-
-bool StringToInt64(const std::string& input, int64* output);
-bool StringToInt64(std::string::const_iterator begin,
- std::string::const_iterator end,
- int64* output);
-bool StringToInt64(const char* begin, const char* end, int64* output);
-
-bool StringToInt64(const string16& input, int64* output);
-bool StringToInt64(string16::const_iterator begin,
- string16::const_iterator end,
- int64* output);
-bool StringToInt64(const char16* begin, const char16* end, int64* output);
+BASE_API bool StringToInt(const std::string& input, int* output);
+BASE_API bool StringToInt(std::string::const_iterator begin,
+ std::string::const_iterator end,
+ int* output);
+BASE_API bool StringToInt(const char* begin, const char* end, int* output);
+
+BASE_API bool StringToInt(const string16& input, int* output);
+BASE_API bool StringToInt(string16::const_iterator begin,
+ string16::const_iterator end,
+ int* output);
+BASE_API bool StringToInt(const char16* begin, const char16* end, int* output);
+
+BASE_API bool StringToInt64(const std::string& input, int64* output);
+BASE_API bool StringToInt64(std::string::const_iterator begin,
+ std::string::const_iterator end,
+ int64* output);
+BASE_API bool StringToInt64(const char* begin, const char* end, int64* output);
+
+BASE_API bool StringToInt64(const string16& input, int64* output);
+BASE_API bool StringToInt64(string16::const_iterator begin,
+ string16::const_iterator end,
+ int64* output);
+BASE_API bool StringToInt64(const char16* begin, const char16* end,
+ int64* output);
// For floating-point conversions, only conversions of input strings in decimal
// form are defined to work. Behavior with strings representing floating-point
@@ -87,7 +89,7 @@ bool StringToInt64(const char16* begin, const char16* end, int64* output);
// NaN and inf) is undefined. Otherwise, these behave the same as the integral
// variants. This expects the input string to NOT be specific to the locale.
// If your input is locale specific, use ICU to read the number.
-bool StringToDouble(const std::string& input, double* output);
+BASE_API bool StringToDouble(const std::string& input, double* output);
// Hex encoding ----------------------------------------------------------------
@@ -97,20 +99,21 @@ bool StringToDouble(const std::string& input, double* output);
// you suspect that the data you want to format might be large, the absolute
// max size for |size| should be is
// std::numeric_limits<size_t>::max() / 2
-std::string HexEncode(const void* bytes, size_t size);
+BASE_API std::string HexEncode(const void* bytes, size_t size);
// Best effort conversion, see StringToInt above for restrictions.
-bool HexStringToInt(const std::string& input, int* output);
-bool HexStringToInt(std::string::const_iterator begin,
- std::string::const_iterator end,
- int* output);
-bool HexStringToInt(const char* begin, const char* end, int* output);
+BASE_API bool HexStringToInt(const std::string& input, int* output);
+BASE_API bool HexStringToInt(std::string::const_iterator begin,
+ std::string::const_iterator end,
+ int* output);
+BASE_API bool HexStringToInt(const char* begin, const char* end, int* output);
// Similar to the previous functions, except that output is a vector of bytes.
// |*output| will contain as many bytes as were successfully parsed prior to the
// error. There is no overflow, but input.size() must be evenly divisible by 2.
// Leading 0x or +/- are not allowed.
-bool HexStringToBytes(const std::string& input, std::vector<uint8>* output);
+BASE_API bool HexStringToBytes(const std::string& input,
+ std::vector<uint8>* output);
} // namespace base
diff --git a/base/string_piece.cc b/base/string_piece.cc
index 3ccb4f0..bf6291c 100644
--- a/base/string_piece.cc
+++ b/base/string_piece.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
// Copied from strings/stringpiece.cc with modifications
@@ -12,11 +12,6 @@ namespace base {
typedef StringPiece::size_type size_type;
-std::ostream& operator<<(std::ostream& o, const StringPiece& piece) {
- o.write(piece.data(), static_cast<std::streamsize>(piece.size()));
- return o;
-}
-
bool operator==(const StringPiece& x, const StringPiece& y) {
if (x.size() != y.size())
return false;
diff --git a/base/string_piece.h b/base/string_piece.h
index 64326e1..60380b1 100644
--- a/base/string_piece.h
+++ b/base/string_piece.h
@@ -21,11 +21,12 @@
#include <string>
+#include "base/base_api.h"
#include "base/basictypes.h"
namespace base {
-class StringPiece {
+class BASE_API StringPiece {
public:
// standard STL container boilerplate
typedef size_t size_type;
@@ -163,7 +164,7 @@ class StringPiece {
size_type length_;
};
-bool operator==(const StringPiece& x, const StringPiece& y);
+BASE_API bool operator==(const StringPiece& x, const StringPiece& y);
inline bool operator!=(const StringPiece& x, const StringPiece& y) {
return !(x == y);
diff --git a/base/string_split.h b/base/string_split.h
index 9a9030a..f2e8c86 100644
--- a/base/string_split.h
+++ b/base/string_split.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -10,6 +10,7 @@
#include <utility>
#include <vector>
+#include "base/base_api.h"
#include "base/string16.h"
namespace base {
@@ -22,52 +23,52 @@ namespace base {
// Where wchar_t is char16 (i.e. Windows), |c| must be in BMP
// (Basic Multilingual Plane). Elsewhere (Linux/Mac), wchar_t
// should be a valid Unicode code point (32-bit).
-void SplitString(const std::wstring& str,
- wchar_t c,
- std::vector<std::wstring>* r);
+BASE_API void SplitString(const std::wstring& str,
+ wchar_t c,
+ std::vector<std::wstring>* r);
// NOTE: |c| must be in BMP (Basic Multilingual Plane)
-void SplitString(const string16& str,
- char16 c,
- std::vector<string16>* r);
+BASE_API void SplitString(const string16& str,
+ char16 c,
+ std::vector<string16>* r);
// |str| should not be in a multi-byte encoding like Shift-JIS or GBK in which
// the trailing byte of a multi-byte character can be in the ASCII range.
// UTF-8, and other single/multi-byte ASCII-compatible encodings are OK.
// Note: |c| must be in the ASCII range.
-void SplitString(const std::string& str,
- char c,
- std::vector<std::string>* r);
+BASE_API void SplitString(const std::string& str,
+ char c,
+ std::vector<std::string>* r);
-bool SplitStringIntoKeyValues(
+BASE_API bool SplitStringIntoKeyValues(
const std::string& line,
char key_value_delimiter,
std::string* key, std::vector<std::string>* values);
-bool SplitStringIntoKeyValuePairs(
+BASE_API bool SplitStringIntoKeyValuePairs(
const std::string& line,
char key_value_delimiter,
char key_value_pair_delimiter,
std::vector<std::pair<std::string, std::string> >* kv_pairs);
// The same as SplitString, but use a substring delimiter instead of a char.
-void SplitStringUsingSubstr(const string16& str,
- const string16& s,
- std::vector<string16>* r);
-void SplitStringUsingSubstr(const std::string& str,
- const std::string& s,
- std::vector<std::string>* r);
+BASE_API void SplitStringUsingSubstr(const string16& str,
+ const string16& s,
+ std::vector<string16>* r);
+BASE_API void SplitStringUsingSubstr(const std::string& str,
+ const std::string& s,
+ std::vector<std::string>* r);
// The same as SplitString, but don't trim white space.
// NOTE: |c| must be in BMP (Basic Multilingual Plane)
-void SplitStringDontTrim(const string16& str,
- char16 c,
- std::vector<string16>* r);
+BASE_API void SplitStringDontTrim(const string16& str,
+ char16 c,
+ std::vector<string16>* r);
// |str| should not be in a multi-byte encoding like Shift-JIS or GBK in which
// the trailing byte of a multi-byte character can be in the ASCII range.
// UTF-8, and other single/multi-byte ASCII-compatible encodings are OK.
// Note: |c| must be in the ASCII range.
-void SplitStringDontTrim(const std::string& str,
- char c,
- std::vector<std::string>* r);
+BASE_API void SplitStringDontTrim(const std::string& str,
+ char c,
+ std::vector<std::string>* r);
// WARNING: this uses whitespace as defined by the HTML5 spec. If you need
// a function similar to this but want to trim all types of whitespace, then
@@ -77,12 +78,12 @@ void SplitStringDontTrim(const std::string& str,
// Splits the string along whitespace (where whitespace is the five space
// characters defined by HTML 5). Each contiguous block of non-whitespace
// characters is added to result.
-void SplitStringAlongWhitespace(const std::wstring& str,
- std::vector<std::wstring>* result);
-void SplitStringAlongWhitespace(const string16& str,
- std::vector<string16>* result);
-void SplitStringAlongWhitespace(const std::string& str,
- std::vector<std::string>* result);
+BASE_API void SplitStringAlongWhitespace(const std::wstring& str,
+ std::vector<std::wstring>* result);
+BASE_API void SplitStringAlongWhitespace(const string16& str,
+ std::vector<string16>* result);
+BASE_API void SplitStringAlongWhitespace(const std::string& str,
+ std::vector<std::string>* result);
} // namespace base
diff --git a/base/string_util.cc b/base/string_util.cc
index b2d9e6c..7198dec 100644
--- a/base/string_util.cc
+++ b/base/string_util.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -22,7 +22,7 @@
#include "base/basictypes.h"
#include "base/logging.h"
-#include "base/singleton.h"
+#include "base/memory/singleton.h"
#include "base/third_party/dmg_fp/dmg_fp.h"
#include "base/utf_string_conversion_utils.h"
#include "base/utf_string_conversions.h"
diff --git a/base/string_util.h b/base/string_util.h
index ed7adec..81d31d3 100644
--- a/base/string_util.h
+++ b/base/string_util.h
@@ -13,6 +13,7 @@
#include <string>
#include <vector>
+#include "base/base_api.h"
#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/string16.h"
@@ -35,28 +36,30 @@ namespace base {
// Compares the two strings s1 and s2 without regard to case using
// the current locale; returns 0 if they are equal, 1 if s1 > s2, and -1 if
// s2 > s1 according to a lexicographic comparison.
-int strcasecmp(const char* s1, const char* s2);
+BASE_API int strcasecmp(const char* s1, const char* s2);
// Compares up to count characters of s1 and s2 without regard to case using
// the current locale; returns 0 if they are equal, 1 if s1 > s2, and -1 if
// s2 > s1 according to a lexicographic comparison.
-int strncasecmp(const char* s1, const char* s2, size_t count);
+BASE_API int strncasecmp(const char* s1, const char* s2, size_t count);
// Same as strncmp but for char16 strings.
-int strncmp16(const char16* s1, const char16* s2, size_t count);
+BASE_API int strncmp16(const char16* s1, const char16* s2, size_t count);
// Wrapper for vsnprintf that always null-terminates and always returns the
// number of characters that would be in an untruncated formatted
// string, even when truncation occurs.
-int vsnprintf(char* buffer, size_t size, const char* format, va_list arguments)
+BASE_API int vsnprintf(char* buffer, size_t size, const char* format,
+ va_list arguments)
PRINTF_FORMAT(3, 0);
// vswprintf always null-terminates, but when truncation occurs, it will either
// return -1 or the number of characters that would be in an untruncated
// formatted string. The actual return value depends on the underlying
// C library's vswprintf implementation.
-int vswprintf(wchar_t* buffer, size_t size,
- const wchar_t* format, va_list arguments) WPRINTF_FORMAT(3, 0);
+BASE_API int vswprintf(wchar_t* buffer, size_t size,
+ const wchar_t* format, va_list arguments)
+ WPRINTF_FORMAT(3, 0);
// Some of these implementations need to be inlined.
@@ -90,8 +93,8 @@ inline int swprintf(wchar_t* buffer, size_t size, const wchar_t* format, ...) {
// long as |dst_size| is not 0. Returns the length of |src| in characters.
// If the return value is >= dst_size, then the output was truncated.
// NOTE: All sizes are in number of characters, NOT in bytes.
-size_t strlcpy(char* dst, const char* src, size_t dst_size);
-size_t wcslcpy(wchar_t* dst, const wchar_t* src, size_t dst_size);
+BASE_API size_t strlcpy(char* dst, const char* src, size_t dst_size);
+BASE_API size_t wcslcpy(wchar_t* dst, const wchar_t* src, size_t dst_size);
// Scan a wprintf format string to determine whether it's portable across a
// variety of systems. This function only checks that the conversion
@@ -114,7 +117,7 @@ size_t wcslcpy(wchar_t* dst, const wchar_t* src, size_t dst_size);
// working with wprintf.
//
// This function is intended to be called from base::vswprintf.
-bool IsWprintfFormatPortable(const wchar_t* format);
+BASE_API bool IsWprintfFormatPortable(const wchar_t* format);
// ASCII-specific tolower. The standard library's tolower is locale sensitive,
// so we don't want to use it here.
@@ -165,9 +168,9 @@ template<typename Char> struct CaseInsensitiveCompareASCII {
// have an empty string to use (e.g. in an error case). These should not be
// used as initializers, function arguments, or return values for functions
// which return by value or outparam.
-const std::string& EmptyString();
-const std::wstring& EmptyWString();
-const string16& EmptyString16();
+BASE_API const std::string& EmptyString();
+BASE_API const std::wstring& EmptyWString();
+BASE_API const string16& EmptyString16();
extern const wchar_t kWhitespaceWide[];
extern const char16 kWhitespaceUTF16[];
@@ -178,33 +181,33 @@ extern const char kUtf8ByteOrderMark[];
// Removes characters in remove_chars from anywhere in input. Returns true if
// any characters were removed.
// NOTE: Safe to use the same variable for both input and output.
-bool RemoveChars(const std::wstring& input,
- const wchar_t remove_chars[],
- std::wstring* output);
-bool RemoveChars(const string16& input,
- const char16 remove_chars[],
- string16* output);
-bool RemoveChars(const std::string& input,
- const char remove_chars[],
- std::string* output);
+BASE_API bool RemoveChars(const std::wstring& input,
+ const wchar_t remove_chars[],
+ std::wstring* output);
+BASE_API bool RemoveChars(const string16& input,
+ const char16 remove_chars[],
+ string16* output);
+BASE_API bool RemoveChars(const std::string& input,
+ const char remove_chars[],
+ std::string* output);
// Removes characters in trim_chars from the beginning and end of input.
// NOTE: Safe to use the same variable for both input and output.
-bool TrimString(const std::wstring& input,
- const wchar_t trim_chars[],
- std::wstring* output);
-bool TrimString(const string16& input,
- const char16 trim_chars[],
- string16* output);
-bool TrimString(const std::string& input,
- const char trim_chars[],
- std::string* output);
+BASE_API bool TrimString(const std::wstring& input,
+ const wchar_t trim_chars[],
+ std::wstring* output);
+BASE_API bool TrimString(const string16& input,
+ const char16 trim_chars[],
+ string16* output);
+BASE_API bool TrimString(const std::string& input,
+ const char trim_chars[],
+ std::string* output);
// Truncates a string to the nearest UTF-8 character that will leave
// the string less than or equal to the specified byte size.
-void TruncateUTF8ToByteSize(const std::string& input,
- const size_t byte_size,
- std::string* output);
+BASE_API void TruncateUTF8ToByteSize(const std::string& input,
+ const size_t byte_size,
+ std::string* output);
// Trims any whitespace from either end of the input string. Returns where
// whitespace was found.
@@ -219,21 +222,21 @@ enum TrimPositions {
TRIM_TRAILING = 1 << 1,
TRIM_ALL = TRIM_LEADING | TRIM_TRAILING,
};
-TrimPositions TrimWhitespace(const std::wstring& input,
- TrimPositions positions,
- std::wstring* output);
-TrimPositions TrimWhitespace(const string16& input,
- TrimPositions positions,
- string16* output);
-TrimPositions TrimWhitespaceASCII(const std::string& input,
- TrimPositions positions,
- std::string* output);
+BASE_API TrimPositions TrimWhitespace(const std::wstring& input,
+ TrimPositions positions,
+ std::wstring* output);
+BASE_API TrimPositions TrimWhitespace(const string16& input,
+ TrimPositions positions,
+ string16* output);
+BASE_API TrimPositions TrimWhitespaceASCII(const std::string& input,
+ TrimPositions positions,
+ std::string* output);
// Deprecated. This function is only for backward compatibility and calls
// TrimWhitespaceASCII().
-TrimPositions TrimWhitespace(const std::string& input,
- TrimPositions positions,
- std::string* output);
+BASE_API TrimPositions TrimWhitespace(const std::string& input,
+ TrimPositions positions,
+ std::string* output);
// Searches for CR or LF characters. Removes all contiguous whitespace
// strings that contain them. This is useful when trying to deal with text
@@ -243,33 +246,35 @@ TrimPositions TrimWhitespace(const std::string& input,
// (2) If |trim_sequences_with_line_breaks| is true, any other whitespace
// sequences containing a CR or LF are trimmed.
// (3) All other whitespace sequences are converted to single spaces.
-std::wstring CollapseWhitespace(const std::wstring& text,
- bool trim_sequences_with_line_breaks);
-string16 CollapseWhitespace(const string16& text,
- bool trim_sequences_with_line_breaks);
-std::string CollapseWhitespaceASCII(const std::string& text,
- bool trim_sequences_with_line_breaks);
+BASE_API std::wstring CollapseWhitespace(const std::wstring& text,
+ bool trim_sequences_with_line_breaks);
+BASE_API string16 CollapseWhitespace(const string16& text,
+ bool trim_sequences_with_line_breaks);
+BASE_API std::string CollapseWhitespaceASCII(
+ const std::string& text, bool trim_sequences_with_line_breaks);
// Returns true if the passed string is empty or contains only white-space
// characters.
-bool ContainsOnlyWhitespaceASCII(const std::string& str);
-bool ContainsOnlyWhitespace(const string16& str);
+BASE_API bool ContainsOnlyWhitespaceASCII(const std::string& str);
+BASE_API bool ContainsOnlyWhitespace(const string16& str);
// Returns true if |input| is empty or contains only characters found in
// |characters|.
-bool ContainsOnlyChars(const std::wstring& input,
- const std::wstring& characters);
-bool ContainsOnlyChars(const string16& input, const string16& characters);
-bool ContainsOnlyChars(const std::string& input, const std::string& characters);
+BASE_API bool ContainsOnlyChars(const std::wstring& input,
+ const std::wstring& characters);
+BASE_API bool ContainsOnlyChars(const string16& input,
+ const string16& characters);
+BASE_API bool ContainsOnlyChars(const std::string& input,
+ const std::string& characters);
// Converts to 7-bit ASCII by truncating. The result must be known to be ASCII
// beforehand.
-std::string WideToASCII(const std::wstring& wide);
-std::string UTF16ToASCII(const string16& utf16);
+BASE_API std::string WideToASCII(const std::wstring& wide);
+BASE_API std::string UTF16ToASCII(const string16& utf16);
// Converts the given wide string to the corresponding Latin1. This will fail
// (return false) if any characters are more than 255.
-bool WideToLatin1(const std::wstring& wide, std::string* latin1);
+BASE_API bool WideToLatin1(const std::wstring& wide, std::string* latin1);
// Returns true if the specified string matches the criteria. How can a wide
// string be 8-bit or UTF8? It contains only characters that are < 256 (in the
@@ -282,10 +287,10 @@ bool WideToLatin1(const std::wstring& wide, std::string* latin1);
// to have the maximum 'discriminating' power from other encodings. If
// there's a use case for just checking the structural validity, we have to
// add a new function for that.
-bool IsStringUTF8(const std::string& str);
-bool IsStringASCII(const std::wstring& str);
-bool IsStringASCII(const base::StringPiece& str);
-bool IsStringASCII(const string16& str);
+BASE_API bool IsStringUTF8(const std::string& str);
+BASE_API bool IsStringASCII(const std::wstring& str);
+BASE_API bool IsStringASCII(const base::StringPiece& str);
+BASE_API bool IsStringASCII(const string16& str);
// Converts the elements of the given string. This version uses a pointer to
// clearly differentiate it from the non-pointer variant.
@@ -319,55 +324,55 @@ template <class str> inline str StringToUpperASCII(const str& s) {
// string. This is useful for doing checking if an input string matches some
// token, and it is optimized to avoid intermediate string copies. This API is
// borrowed from the equivalent APIs in Mozilla.
-bool LowerCaseEqualsASCII(const std::string& a, const char* b);
-bool LowerCaseEqualsASCII(const std::wstring& a, const char* b);
-bool LowerCaseEqualsASCII(const string16& a, const char* b);
+BASE_API bool LowerCaseEqualsASCII(const std::string& a, const char* b);
+BASE_API bool LowerCaseEqualsASCII(const std::wstring& a, const char* b);
+BASE_API bool LowerCaseEqualsASCII(const string16& a, const char* b);
// Same thing, but with string iterators instead.
-bool LowerCaseEqualsASCII(std::string::const_iterator a_begin,
- std::string::const_iterator a_end,
- const char* b);
-bool LowerCaseEqualsASCII(std::wstring::const_iterator a_begin,
- std::wstring::const_iterator a_end,
- const char* b);
-bool LowerCaseEqualsASCII(string16::const_iterator a_begin,
- string16::const_iterator a_end,
- const char* b);
-bool LowerCaseEqualsASCII(const char* a_begin,
- const char* a_end,
- const char* b);
-bool LowerCaseEqualsASCII(const wchar_t* a_begin,
- const wchar_t* a_end,
- const char* b);
-bool LowerCaseEqualsASCII(const char16* a_begin,
- const char16* a_end,
- const char* b);
+BASE_API bool LowerCaseEqualsASCII(std::string::const_iterator a_begin,
+ std::string::const_iterator a_end,
+ const char* b);
+BASE_API bool LowerCaseEqualsASCII(std::wstring::const_iterator a_begin,
+ std::wstring::const_iterator a_end,
+ const char* b);
+BASE_API bool LowerCaseEqualsASCII(string16::const_iterator a_begin,
+ string16::const_iterator a_end,
+ const char* b);
+BASE_API bool LowerCaseEqualsASCII(const char* a_begin,
+ const char* a_end,
+ const char* b);
+BASE_API bool LowerCaseEqualsASCII(const wchar_t* a_begin,
+ const wchar_t* a_end,
+ const char* b);
+BASE_API bool LowerCaseEqualsASCII(const char16* a_begin,
+ const char16* a_end,
+ const char* b);
// Performs a case-sensitive string compare. The behavior is undefined if both
// strings are not ASCII.
-bool EqualsASCII(const string16& a, const base::StringPiece& b);
+BASE_API bool EqualsASCII(const string16& a, const base::StringPiece& b);
// Returns true if str starts with search, or false otherwise.
-bool StartsWithASCII(const std::string& str,
- const std::string& search,
- bool case_sensitive);
-bool StartsWith(const std::wstring& str,
- const std::wstring& search,
- bool case_sensitive);
-bool StartsWith(const string16& str,
- const string16& search,
- bool case_sensitive);
+BASE_API bool StartsWithASCII(const std::string& str,
+ const std::string& search,
+ bool case_sensitive);
+BASE_API bool StartsWith(const std::wstring& str,
+ const std::wstring& search,
+ bool case_sensitive);
+BASE_API bool StartsWith(const string16& str,
+ const string16& search,
+ bool case_sensitive);
// Returns true if str ends with search, or false otherwise.
-bool EndsWith(const std::string& str,
- const std::string& search,
- bool case_sensitive);
-bool EndsWith(const std::wstring& str,
- const std::wstring& search,
- bool case_sensitive);
-bool EndsWith(const string16& str,
- const string16& search,
- bool case_sensitive);
+BASE_API bool EndsWith(const std::string& str,
+ const std::string& search,
+ bool case_sensitive);
+BASE_API bool EndsWith(const std::wstring& str,
+ const std::wstring& search,
+ bool case_sensitive);
+BASE_API bool EndsWith(const string16& str,
+ const string16& search,
+ bool case_sensitive);
// Determines the type of ASCII character, independent of locale (the C
@@ -418,33 +423,34 @@ enum DataUnits {
// Return the unit type that is appropriate for displaying the amount of bytes
// passed in.
-DataUnits GetByteDisplayUnits(int64 bytes);
+BASE_API DataUnits GetByteDisplayUnits(int64 bytes);
// Return a byte string in human-readable format, displayed in units appropriate
// specified by 'units', with an optional unit suffix.
// Ex: FormatBytes(512, DATA_UNITS_KIBIBYTE, true) => "0.5 KB"
// Ex: FormatBytes(10*1024, DATA_UNITS_MEBIBYTE, false) => "0.1"
-string16 FormatBytes(int64 bytes, DataUnits units, bool show_units);
+BASE_API string16 FormatBytes(int64 bytes, DataUnits units, bool show_units);
// As above, but with "/s" units.
// Ex: FormatSpeed(512, DATA_UNITS_KIBIBYTE, true) => "0.5 KB/s"
// Ex: FormatSpeed(10*1024, DATA_UNITS_MEBIBYTE, false) => "0.1"
-string16 FormatSpeed(int64 bytes, DataUnits units, bool show_units);
+BASE_API string16 FormatSpeed(int64 bytes, DataUnits units, bool show_units);
// Return a number formated with separators in the user's locale way.
// Ex: FormatNumber(1234567) => 1,234,567
-string16 FormatNumber(int64 number);
+BASE_API string16 FormatNumber(int64 number);
// Starting at |start_offset| (usually 0), replace the first instance of
// |find_this| with |replace_with|.
-void ReplaceFirstSubstringAfterOffset(string16* str,
- string16::size_type start_offset,
- const string16& find_this,
- const string16& replace_with);
-void ReplaceFirstSubstringAfterOffset(std::string* str,
- std::string::size_type start_offset,
- const std::string& find_this,
- const std::string& replace_with);
+BASE_API void ReplaceFirstSubstringAfterOffset(string16* str,
+ string16::size_type start_offset,
+ const string16& find_this,
+ const string16& replace_with);
+BASE_API void ReplaceFirstSubstringAfterOffset(
+ std::string* str,
+ std::string::size_type start_offset,
+ const std::string& find_this,
+ const std::string& replace_with);
// Starting at |start_offset| (usually 0), look through |str| and replace all
// instances of |find_this| with |replace_with|.
@@ -452,14 +458,14 @@ void ReplaceFirstSubstringAfterOffset(std::string* str,
// This does entire substrings; use std::replace in <algorithm> for single
// characters, for example:
// std::replace(str.begin(), str.end(), 'a', 'b');
-void ReplaceSubstringsAfterOffset(string16* str,
- string16::size_type start_offset,
- const string16& find_this,
- const string16& replace_with);
-void ReplaceSubstringsAfterOffset(std::string* str,
- std::string::size_type start_offset,
- const std::string& find_this,
- const std::string& replace_with);
+BASE_API void ReplaceSubstringsAfterOffset(string16* str,
+ string16::size_type start_offset,
+ const string16& find_this,
+ const string16& replace_with);
+BASE_API void ReplaceSubstringsAfterOffset(std::string* str,
+ std::string::size_type start_offset,
+ const std::string& find_this,
+ const std::string& replace_with);
// This is mpcomplete's pattern for saving a string copy when dealing with
// a function that writes results into a wchar_t[] and wanting the result to
@@ -489,48 +495,49 @@ inline typename string_type::value_type* WriteInto(string_type* str,
// Splits a string into its fields delimited by any of the characters in
// |delimiters|. Each field is added to the |tokens| vector. Returns the
// number of tokens found.
-size_t Tokenize(const std::wstring& str,
- const std::wstring& delimiters,
- std::vector<std::wstring>* tokens);
-size_t Tokenize(const string16& str,
- const string16& delimiters,
- std::vector<string16>* tokens);
-size_t Tokenize(const std::string& str,
- const std::string& delimiters,
- std::vector<std::string>* tokens);
-size_t Tokenize(const base::StringPiece& str,
- const base::StringPiece& delimiters,
- std::vector<base::StringPiece>* tokens);
+BASE_API size_t Tokenize(const std::wstring& str,
+ const std::wstring& delimiters,
+ std::vector<std::wstring>* tokens);
+BASE_API size_t Tokenize(const string16& str,
+ const string16& delimiters,
+ std::vector<string16>* tokens);
+BASE_API size_t Tokenize(const std::string& str,
+ const std::string& delimiters,
+ std::vector<std::string>* tokens);
+BASE_API size_t Tokenize(const base::StringPiece& str,
+ const base::StringPiece& delimiters,
+ std::vector<base::StringPiece>* tokens);
// Does the opposite of SplitString().
-string16 JoinString(const std::vector<string16>& parts, char16 s);
-std::string JoinString(const std::vector<std::string>& parts, char s);
+BASE_API string16 JoinString(const std::vector<string16>& parts, char16 s);
+BASE_API std::string JoinString(const std::vector<std::string>& parts, char s);
// Replace $1-$2-$3..$9 in the format string with |a|-|b|-|c|..|i| respectively.
// Additionally, any number of consecutive '$' characters is replaced by that
// number less one. Eg $$->$, $$$->$$, etc. The offsets parameter here can be
// NULL. This only allows you to use up to nine replacements.
-string16 ReplaceStringPlaceholders(const string16& format_string,
- const std::vector<string16>& subst,
- std::vector<size_t>* offsets);
+BASE_API string16 ReplaceStringPlaceholders(const string16& format_string,
+ const std::vector<string16>& subst,
+ std::vector<size_t>* offsets);
-std::string ReplaceStringPlaceholders(const base::StringPiece& format_string,
- const std::vector<std::string>& subst,
- std::vector<size_t>* offsets);
+BASE_API std::string ReplaceStringPlaceholders(
+ const base::StringPiece& format_string,
+ const std::vector<std::string>& subst,
+ std::vector<size_t>* offsets);
// Single-string shortcut for ReplaceStringHolders. |offset| may be NULL.
-string16 ReplaceStringPlaceholders(const string16& format_string,
- const string16& a,
- size_t* offset);
+BASE_API string16 ReplaceStringPlaceholders(const string16& format_string,
+ const string16& a,
+ size_t* offset);
// Returns true if the string passed in matches the pattern. The pattern
// string can contain wildcards like * and ?
// The backslash character (\) is an escape character for * and ?
// We limit the patterns to having a max of 16 * or ? characters.
// ? matches 0 or 1 character, while * matches 0 or more characters.
-bool MatchPattern(const base::StringPiece& string,
- const base::StringPiece& pattern);
-bool MatchPattern(const string16& string, const string16& pattern);
+BASE_API bool MatchPattern(const base::StringPiece& string,
+ const base::StringPiece& pattern);
+BASE_API bool MatchPattern(const string16& string, const string16& pattern);
// Hack to convert any char-like type to its unsigned counterpart.
// For example, it will convert char, signed char and unsigned char to unsigned
diff --git a/base/string_util_posix.h b/base/string_util_posix.h
index 6053ada..d238f7f 100644
--- a/base/string_util_posix.h
+++ b/base/string_util_posix.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -44,8 +44,15 @@ inline int strncmp16(const char16* s1, const char16* s2, size_t count) {
inline int vswprintf(wchar_t* buffer, size_t size,
const wchar_t* format, va_list arguments) {
+#if defined(OS_OPENBSD)
+ // TODO(phajdan.jr): There is a patch to add vswprintf to OpenBSD,
+ // http://marc.info/?l=openbsd-tech&m=130003157729839&w=2
+ NOTIMPLEMENTED();
+ return -1;
+#else
DCHECK(IsWprintfFormatPortable(format));
return ::vswprintf(buffer, size, format, arguments);
+#endif
}
} // namespace base
diff --git a/base/stringprintf.h b/base/stringprintf.h
index 9170ddd..fb32f20 100644
--- a/base/stringprintf.h
+++ b/base/stringprintf.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -9,37 +9,42 @@
#include <string>
+#include "base/base_api.h"
#include "base/compiler_specific.h"
namespace base {
// Return a C++ string given printf-like input.
-std::string StringPrintf(const char* format, ...) PRINTF_FORMAT(1, 2);
-std::wstring StringPrintf(const wchar_t* format, ...) WPRINTF_FORMAT(1, 2);
+BASE_API std::string StringPrintf(const char* format, ...) PRINTF_FORMAT(1, 2);
+BASE_API std::wstring StringPrintf(const wchar_t* format, ...)
+ WPRINTF_FORMAT(1, 2);
// Return a C++ string given vprintf-like input.
-std::string StringPrintV(const char* format, va_list ap) PRINTF_FORMAT(1, 0);
+BASE_API std::string StringPrintV(const char* format, va_list ap)
+ PRINTF_FORMAT(1, 0);
// Store result into a supplied string and return it.
-const std::string& SStringPrintf(std::string* dst, const char* format, ...)
+BASE_API const std::string& SStringPrintf(std::string* dst,
+ const char* format, ...)
PRINTF_FORMAT(2, 3);
-const std::wstring& SStringPrintf(std::wstring* dst,
- const wchar_t* format, ...)
+BASE_API const std::wstring& SStringPrintf(std::wstring* dst,
+ const wchar_t* format, ...)
WPRINTF_FORMAT(2, 3);
// Append result to a supplied string.
-void StringAppendF(std::string* dst, const char* format, ...)
+BASE_API void StringAppendF(std::string* dst, const char* format, ...)
PRINTF_FORMAT(2, 3);
// TODO(evanm): this is only used in a few places in the code;
// replace with string16 version.
-void StringAppendF(std::wstring* dst, const wchar_t* format, ...)
+BASE_API void StringAppendF(std::wstring* dst, const wchar_t* format, ...)
WPRINTF_FORMAT(2, 3);
// Lower-level routine that takes a va_list and appends to a specified
// string. All other routines are just convenience wrappers around it.
-void StringAppendV(std::string* dst, const char* format, va_list ap)
+BASE_API void StringAppendV(std::string* dst, const char* format, va_list ap)
PRINTF_FORMAT(2, 0);
-void StringAppendV(std::wstring* dst, const wchar_t* format, va_list ap)
+BASE_API void StringAppendV(std::wstring* dst,
+ const wchar_t* format, va_list ap)
WPRINTF_FORMAT(2, 0);
} // namespace base
diff --git a/base/sync_socket.h b/base/sync_socket.h
index 1408b47..bcebbdf 100644
--- a/base/sync_socket.h
+++ b/base/sync_socket.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -16,9 +16,11 @@
#endif
#include <sys/types.h>
+#include "base/base_api.h"
+
namespace base {
-class SyncSocket {
+class BASE_API SyncSocket {
public:
#if defined(OS_WIN)
typedef HANDLE Handle;
diff --git a/base/synchronization/cancellation_flag.h b/base/synchronization/cancellation_flag.h
index 29ecd89..5738929 100644
--- a/base/synchronization/cancellation_flag.h
+++ b/base/synchronization/cancellation_flag.h
@@ -6,6 +6,7 @@
#define BASE_SYNCHRONIZATION_CANCELLATION_FLAG_H_
#pragma once
+#include "base/base_api.h"
#include "base/atomicops.h"
#include "base/threading/platform_thread.h"
@@ -16,7 +17,7 @@ namespace base {
// is thread-safe.
//
// This class IS NOT intended for synchronization between threads.
-class CancellationFlag {
+class BASE_API CancellationFlag {
public:
CancellationFlag() : flag_(false) {
#if !defined(NDEBUG)
diff --git a/base/synchronization/condition_variable.h b/base/synchronization/condition_variable.h
index db75a49..d70d4cd 100644
--- a/base/synchronization/condition_variable.h
+++ b/base/synchronization/condition_variable.h
@@ -74,6 +74,7 @@
#include <pthread.h>
#endif
+#include "base/base_api.h"
#include "base/basictypes.h"
#include "base/synchronization/lock.h"
@@ -81,7 +82,7 @@ namespace base {
class TimeDelta;
-class ConditionVariable {
+class BASE_API ConditionVariable {
public:
// Construct a cv for use with ONLY one user lock.
explicit ConditionVariable(Lock* user_lock);
diff --git a/base/synchronization/condition_variable_unittest.cc b/base/synchronization/condition_variable_unittest.cc
index cf18320..808ecde 100644
--- a/base/synchronization/condition_variable_unittest.cc
+++ b/base/synchronization/condition_variable_unittest.cc
@@ -9,7 +9,7 @@
#include <vector>
#include "base/logging.h"
-#include "base/scoped_ptr.h"
+#include "base/memory/scoped_ptr.h"
#include "base/spin_wait.h"
#include "base/synchronization/condition_variable.h"
#include "base/synchronization/lock.h"
diff --git a/base/synchronization/lock.h b/base/synchronization/lock.h
index f7c9c49..46d1ab3 100644
--- a/base/synchronization/lock.h
+++ b/base/synchronization/lock.h
@@ -6,6 +6,7 @@
#define BASE_SYNCHRONIZATION_LOCK_H_
#pragma once
+#include "base/base_api.h"
#include "base/synchronization/lock_impl.h"
#include "base/threading/platform_thread.h"
@@ -14,7 +15,7 @@ namespace base {
// A convenient wrapper for an OS specific critical section. The only real
// intelligence in this class is in debug mode for the support for the
// AssertAcquired() method.
-class Lock {
+class BASE_API Lock {
public:
#if defined(NDEBUG) // Optimized wrapper implementation
Lock() : lock_() {}
diff --git a/base/synchronization/waitable_event.h b/base/synchronization/waitable_event.h
index 9f357d1..1ab20fa 100644
--- a/base/synchronization/waitable_event.h
+++ b/base/synchronization/waitable_event.h
@@ -6,6 +6,7 @@
#define BASE_SYNCHRONIZATION_WAITABLE_EVENT_H_
#pragma once
+#include "base/base_api.h"
#include "base/basictypes.h"
#if defined(OS_WIN)
@@ -15,7 +16,7 @@
#if defined(OS_POSIX)
#include <list>
#include <utility>
-#include "base/ref_counted.h"
+#include "base/memory/ref_counted.h"
#include "base/synchronization/lock.h"
#endif
@@ -41,7 +42,7 @@ class TimeDelta;
// by a Windows event object. This is intentional. If you are writing Windows
// specific code and you need other features of a Windows event, then you might
// be better off just using an Windows event directly.
-class WaitableEvent {
+class BASE_API WaitableEvent {
public:
// If manual_reset is true, then to set the event state to non-signaled, a
// consumer must call the Reset method. If this parameter is false, then the
diff --git a/base/synchronization/waitable_event_watcher.h b/base/synchronization/waitable_event_watcher.h
index 1b93b66..aa16d0b 100644
--- a/base/synchronization/waitable_event_watcher.h
+++ b/base/synchronization/waitable_event_watcher.h
@@ -15,6 +15,8 @@
#include "base/synchronization/waitable_event.h"
#endif
+#include "base/base_api.h"
+
namespace base {
class Flag;
@@ -58,7 +60,7 @@ class WaitableEvent;
// it with a Watcher. It will act as if the event was never signaled.
// -----------------------------------------------------------------------------
-class WaitableEventWatcher
+class BASE_API WaitableEventWatcher
#if defined(OS_POSIX)
: public MessageLoop::DestructionObserver
#endif
diff --git a/base/sys_info.h b/base/sys_info.h
index adfb250..863e068 100644
--- a/base/sys_info.h
+++ b/base/sys_info.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -6,6 +6,7 @@
#define BASE_SYS_INFO_H_
#pragma once
+#include "base/base_api.h"
#include "base/basictypes.h"
#include <string>
@@ -14,7 +15,7 @@ class FilePath;
namespace base {
-class SysInfo {
+class BASE_API SysInfo {
public:
// Return the number of logical processors/cores on the current machine.
static int NumberOfProcessors();
@@ -40,9 +41,9 @@ class SysInfo {
// Retrieves detailed numeric values for the OS version.
// TODO(port): Implement a Linux version of this method and enable the
// corresponding unit test.
- static void OperatingSystemVersionNumbers(int32 *major_version,
- int32 *minor_version,
- int32 *bugfix_version);
+ static void OperatingSystemVersionNumbers(int32* major_version,
+ int32* minor_version,
+ int32* bugfix_version);
// Returns the CPU architecture of the system. Exact return value may differ
// across platforms.
@@ -72,9 +73,9 @@ class SysInfo {
// Parses /etc/lsb-release to get version information for Google Chrome OS.
// Declared here so it can be exposed for unit testing.
static void ParseLsbRelease(const std::string& lsb_release,
- int32 *major_version,
- int32 *minor_version,
- int32 *bugfix_version);
+ int32* major_version,
+ int32* minor_version,
+ int32* bugfix_version);
#endif
};
diff --git a/base/sys_info_chromeos.cc b/base/sys_info_chromeos.cc
index 5834389..f724f99 100644
--- a/base/sys_info_chromeos.cc
+++ b/base/sys_info_chromeos.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -7,69 +7,107 @@
#include "base/basictypes.h"
#include "base/file_path.h"
#include "base/file_util.h"
+#include "base/lazy_instance.h"
#include "base/string_number_conversions.h"
#include "base/string_tokenizer.h"
#include "base/threading/thread_restrictions.h"
+#include <execinfo.h>
+
namespace base {
-#if defined(GOOGLE_CHROME_BUILD)
-static const char kLinuxStandardBaseVersionKey[] = "GOOGLE_RELEASE";
-#else
-static const char kLinuxStandardBaseVersionKey[] = "DISTRIB_RELEASE";
-#endif
+static const char* kLinuxStandardBaseVersionKeys[] = {
+ "CHROMEOS_RELEASE_VERSION",
+ "GOOGLE_RELEASE",
+ "DISTRIB_RELEASE",
+ NULL
+};
const char kLinuxStandardBaseReleaseFile[] = "/etc/lsb-release";
+struct ChromeOSVersionNumbers {
+ ChromeOSVersionNumbers()
+ : major_version(0),
+ minor_version(0),
+ bugfix_version(0),
+ parsed(false) {
+ }
+
+ int32 major_version;
+ int32 minor_version;
+ int32 bugfix_version;
+ bool parsed;
+};
+
+static base::LazyInstance<ChromeOSVersionNumbers>
+ g_chrome_os_version_numbers(base::LINKER_INITIALIZED);
+
// static
-void SysInfo::OperatingSystemVersionNumbers(int32 *major_version,
- int32 *minor_version,
- int32 *bugfix_version) {
- // The other implementations of SysInfo don't block on the disk.
- // See http://code.google.com/p/chromium/issues/detail?id=60394
- // Perhaps the caller ought to cache this?
- // Temporary allowing while we work the bug out.
- base::ThreadRestrictions::ScopedAllowIO allow_io;
+void SysInfo::OperatingSystemVersionNumbers(int32* major_version,
+ int32* minor_version,
+ int32* bugfix_version) {
+ if (!g_chrome_os_version_numbers.Get().parsed) {
+ // The other implementations of SysInfo don't block on the disk.
+ // See http://code.google.com/p/chromium/issues/detail?id=60394
+ // Perhaps the caller ought to cache this?
+ // Temporary allowing while we work the bug out.
+ base::ThreadRestrictions::ScopedAllowIO allow_io;
- // TODO(cmasone): If this gets called a lot, it may kill performance.
- // consider using static variables to cache these values?
- FilePath path(kLinuxStandardBaseReleaseFile);
- std::string contents;
- if (file_util::ReadFileToString(path, &contents)) {
- ParseLsbRelease(contents, major_version, minor_version, bugfix_version);
+ FilePath path(kLinuxStandardBaseReleaseFile);
+ std::string contents;
+ if (file_util::ReadFileToString(path, &contents)) {
+ g_chrome_os_version_numbers.Get().parsed = true;
+ ParseLsbRelease(contents,
+ &(g_chrome_os_version_numbers.Get().major_version),
+ &(g_chrome_os_version_numbers.Get().minor_version),
+ &(g_chrome_os_version_numbers.Get().bugfix_version));
+ }
}
+ *major_version = g_chrome_os_version_numbers.Get().major_version;
+ *minor_version = g_chrome_os_version_numbers.Get().minor_version;
+ *bugfix_version = g_chrome_os_version_numbers.Get().bugfix_version;
}
// static
std::string SysInfo::GetLinuxStandardBaseVersionKey() {
- return std::string(kLinuxStandardBaseVersionKey);
+ return std::string(kLinuxStandardBaseVersionKeys[0]);
}
// static
void SysInfo::ParseLsbRelease(const std::string& lsb_release,
- int32 *major_version,
- int32 *minor_version,
- int32 *bugfix_version) {
- size_t version_key_index = lsb_release.find(kLinuxStandardBaseVersionKey);
+ int32* major_version,
+ int32* minor_version,
+ int32* bugfix_version) {
+ size_t version_key_index = std::string::npos;
+ for (int i = 0; kLinuxStandardBaseVersionKeys[i] != NULL; ++i) {
+ version_key_index = lsb_release.find(kLinuxStandardBaseVersionKeys[i]);
+ if (std::string::npos != version_key_index) {
+ break;
+ }
+ }
if (std::string::npos == version_key_index) {
return;
}
+
size_t start_index = lsb_release.find_first_of('=', version_key_index);
start_index++; // Move past '='.
size_t length = lsb_release.find_first_of('\n', start_index) - start_index;
std::string version = lsb_release.substr(start_index, length);
StringTokenizer tokenizer(version, ".");
- for (int i = 0; i < 3 && tokenizer.GetNext(); i++) {
- if (0 == i) {
+ // TODO(rkc): Ignore the 0. here; fix this once we move Chrome OS version
+ // numbers from the 0.xx.yyy.zz format to the xx.yyy.zz format.
+ // Refer to http://code.google.com/p/chromium-os/issues/detail?id=15789
+ for (int i = 0; i < 4 && tokenizer.GetNext(); i++) {
+ if (1 == i) {
StringToInt(tokenizer.token_begin(),
tokenizer.token_end(),
major_version);
*minor_version = *bugfix_version = 0;
- } else if (1 == i) {
+ } else if (2 == i) {
StringToInt(tokenizer.token_begin(),
tokenizer.token_end(),
minor_version);
- } else { // 2 == i
+ } else { // 3 == i
StringToInt(tokenizer.token_begin(),
tokenizer.token_end(),
bugfix_version);
diff --git a/base/sys_info_mac.cc b/base/sys_info_mac.cc
index 79caf55..e668421 100644
--- a/base/sys_info_mac.cc
+++ b/base/sys_info_mac.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -14,9 +14,9 @@
namespace base {
// static
-void SysInfo::OperatingSystemVersionNumbers(int32 *major_version,
- int32 *minor_version,
- int32 *bugfix_version) {
+void SysInfo::OperatingSystemVersionNumbers(int32* major_version,
+ int32* minor_version,
+ int32* bugfix_version) {
Gestalt(gestaltSystemVersionMajor,
reinterpret_cast<SInt32*>(major_version));
Gestalt(gestaltSystemVersionMinor,
diff --git a/base/sys_info_unittest.cc b/base/sys_info_unittest.cc
index 3e51890..da17684 100644
--- a/base/sys_info_unittest.cc
+++ b/base/sys_info_unittest.cc
@@ -67,9 +67,9 @@ TEST_F(SysInfoTest, GoogleChromeOSVersionNumbers) {
&os_major_version,
&os_minor_version,
&os_bugfix_version);
- EXPECT_EQ(1, os_major_version);
- EXPECT_EQ(2, os_minor_version);
- EXPECT_EQ(3, os_bugfix_version);
+ EXPECT_EQ(2, os_major_version);
+ EXPECT_EQ(3, os_minor_version);
+ EXPECT_EQ(4, os_bugfix_version);
}
TEST_F(SysInfoTest, GoogleChromeOSVersionNumbersFirst) {
@@ -83,9 +83,9 @@ TEST_F(SysInfoTest, GoogleChromeOSVersionNumbersFirst) {
&os_major_version,
&os_minor_version,
&os_bugfix_version);
- EXPECT_EQ(1, os_major_version);
- EXPECT_EQ(2, os_minor_version);
- EXPECT_EQ(3, os_bugfix_version);
+ EXPECT_EQ(2, os_major_version);
+ EXPECT_EQ(3, os_minor_version);
+ EXPECT_EQ(4, os_bugfix_version);
}
TEST_F(SysInfoTest, GoogleChromeOSNoVersionNumbers) {
diff --git a/base/sys_info_win.cc b/base/sys_info_win.cc
index 83e099c..045d516 100644
--- a/base/sys_info_win.cc
+++ b/base/sys_info_win.cc
@@ -8,16 +8,15 @@
#include "base/file_path.h"
#include "base/logging.h"
-#include "base/scoped_ptr.h"
+#include "base/memory/scoped_ptr.h"
#include "base/stringprintf.h"
+#include "base/win/windows_version.h"
namespace base {
// static
int SysInfo::NumberOfProcessors() {
- SYSTEM_INFO info;
- GetSystemInfo(&info);
- return static_cast<int>(info.dwNumberOfProcessors);
+ return win::OSInfo::GetInstance()->processors();
}
// static
@@ -54,12 +53,17 @@ std::string SysInfo::OperatingSystemName() {
// static
std::string SysInfo::OperatingSystemVersion() {
- OSVERSIONINFO info = {0};
- info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
- GetVersionEx(&info);
-
- return base::StringPrintf("%lu.%lu",
- info.dwMajorVersion, info.dwMinorVersion);
+ win::OSInfo* os_info = win::OSInfo::GetInstance();
+ win::OSInfo::VersionNumber version_number = os_info->version_number();
+ std::string version(StringPrintf("%d.%d", version_number.major,
+ version_number.minor));
+ win::OSInfo::ServicePack service_pack = os_info->service_pack();
+ if (service_pack.major != 0) {
+ version += StringPrintf(" SP%d", service_pack.major);
+ if (service_pack.minor != 0)
+ version += StringPrintf(".%d", service_pack.minor);
+ }
+ return version;
}
// TODO: Implement OperatingSystemVersionComplete, which would include
@@ -88,21 +92,16 @@ int SysInfo::DisplayCount() {
// static
size_t SysInfo::VMAllocationGranularity() {
- SYSTEM_INFO sysinfo;
- GetSystemInfo(&sysinfo);
-
- return sysinfo.dwAllocationGranularity;
+ return win::OSInfo::GetInstance()->allocation_granularity();
}
// static
-void SysInfo::OperatingSystemVersionNumbers(int32 *major_version,
- int32 *minor_version,
- int32 *bugfix_version) {
- OSVERSIONINFO info = {0};
- info.dwOSVersionInfoSize = sizeof(info);
- GetVersionEx(&info);
- *major_version = info.dwMajorVersion;
- *minor_version = info.dwMinorVersion;
+void SysInfo::OperatingSystemVersionNumbers(int32* major_version,
+ int32* minor_version,
+ int32* bugfix_version) {
+ win::OSInfo* os_info = win::OSInfo::GetInstance();
+ *major_version = os_info->version_number().major;
+ *minor_version = os_info->version_number().minor;
*bugfix_version = 0;
}
diff --git a/base/sys_string_conversions.h b/base/sys_string_conversions.h
index a96a687..4cf4b7a 100644
--- a/base/sys_string_conversions.h
+++ b/base/sys_string_conversions.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -11,6 +11,8 @@
// but it is used in some shared code. Dependencies should be minimal.
#include <string>
+
+#include "base/base_api.h"
#include "base/basictypes.h"
#include "base/string16.h"
@@ -29,14 +31,14 @@ class StringPiece;
// Converts between wide and UTF-8 representations of a string. On error, the
// result is system-dependent.
-std::string SysWideToUTF8(const std::wstring& wide);
-std::wstring SysUTF8ToWide(const StringPiece& utf8);
+BASE_API std::string SysWideToUTF8(const std::wstring& wide);
+BASE_API std::wstring SysUTF8ToWide(const StringPiece& utf8);
// Converts between wide and the system multi-byte representations of a string.
// DANGER: This will lose information and can change (on Windows, this can
// change between reboots).
-std::string SysWideToNativeMB(const std::wstring& wide);
-std::wstring SysNativeMBToWide(const StringPiece& native_mb);
+BASE_API std::string SysWideToNativeMB(const std::wstring& wide);
+BASE_API std::wstring SysNativeMBToWide(const StringPiece& native_mb);
// Windows-specific ------------------------------------------------------------
@@ -45,8 +47,10 @@ std::wstring SysNativeMBToWide(const StringPiece& native_mb);
// Converts between 8-bit and wide strings, using the given code page. The
// code page identifier is one accepted by the Windows function
// MultiByteToWideChar().
-std::wstring SysMultiByteToWide(const StringPiece& mb, uint32 code_page);
-std::string SysWideToMultiByte(const std::wstring& wide, uint32 code_page);
+BASE_API std::wstring SysMultiByteToWide(const StringPiece& mb,
+ uint32 code_page);
+BASE_API std::string SysWideToMultiByte(const std::wstring& wide,
+ uint32 code_page);
#endif // defined(OS_WIN)
diff --git a/base/task.h b/base/task.h
index 2deee56..8030169 100644
--- a/base/task.h
+++ b/base/task.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -6,17 +6,18 @@
#define BASE_TASK_H_
#pragma once
-#include "base/raw_scoped_refptr_mismatch_checker.h"
+#include "base/base_api.h"
+#include "base/memory/raw_scoped_refptr_mismatch_checker.h"
+#include "base/memory/weak_ptr.h"
#include "base/tracked.h"
#include "base/tuple.h"
-#include "base/weak_ptr.h"
// Task ------------------------------------------------------------------------
//
// A task is a generic runnable thingy, usually used for running code on a
// different thread or for scheduling future tasks off of the message loop.
-class Task : public tracked_objects::Tracked {
+class BASE_API Task : public tracked_objects::Tracked {
public:
Task();
virtual ~Task();
@@ -25,7 +26,7 @@ class Task : public tracked_objects::Tracked {
virtual void Run() = 0;
};
-class CancelableTask : public Task {
+class BASE_API CancelableTask : public Task {
public:
CancelableTask();
virtual ~CancelableTask();
diff --git a/base/task_queue.h b/base/task_queue.h
index 75b38b2..8bd3cb7 100644
--- a/base/task_queue.h
+++ b/base/task_queue.h
@@ -8,12 +8,13 @@
#include <deque>
+#include "base/base_api.h"
#include "base/task.h"
// A TaskQueue is a queue of tasks waiting to be run. To run the tasks, call
// the Run method. A task queue is itself a Task so that it can be placed in a
// message loop or another task queue.
-class TaskQueue : public Task {
+class BASE_API TaskQueue : public Task {
public:
TaskQueue();
~TaskQueue();
diff --git a/base/task_queue_unittest.cc b/base/task_queue_unittest.cc
index 90fc4cd..f2d2f49 100644
--- a/base/task_queue_unittest.cc
+++ b/base/task_queue_unittest.cc
@@ -1,9 +1,9 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
#include "base/basictypes.h"
-#include "base/scoped_ptr.h"
+#include "base/memory/scoped_ptr.h"
#include "base/task.h"
#include "base/task_queue.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/base/task_unittest.cc b/base/task_unittest.cc
index cc975e0..25c201d 100644
--- a/base/task_unittest.cc
+++ b/base/task_unittest.cc
@@ -1,8 +1,8 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
-#include "base/ref_counted.h"
+#include "base/memory/ref_counted.h"
#include "base/task.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/base/test/OWNERS b/base/test/OWNERS
new file mode 100644
index 0000000..92ecc88
--- /dev/null
+++ b/base/test/OWNERS
@@ -0,0 +1 @@
+phajdan.jr@chromium.org
diff --git a/base/test/test_file_util.h b/base/test/test_file_util.h
index e59456a..9b9389d 100644
--- a/base/test/test_file_util.h
+++ b/base/test/test_file_util.h
@@ -47,6 +47,7 @@ bool HasInternetZoneIdentifier(const FilePath& full_path);
// string16 elsewhere for Unicode strings, but in tests it is frequently
// convenient to be able to compare paths to literals like L"foobar".
std::wstring FilePathAsWString(const FilePath& path);
+FilePath WStringAsFilePath(const std::wstring& path);
} // namespace file_util
diff --git a/base/test/test_file_util_posix.cc b/base/test/test_file_util_posix.cc
index 430e52e..5adbcc2 100644
--- a/base/test/test_file_util_posix.cc
+++ b/base/test/test_file_util_posix.cc
@@ -113,5 +113,8 @@ bool EvictFileFromSystemCache(const FilePath& file) {
std::wstring FilePathAsWString(const FilePath& path) {
return UTF8ToWide(path.value());
}
+FilePath WStringAsFilePath(const std::wstring& path) {
+ return FilePath(WideToUTF8(path));
+}
} // namespace file_util
diff --git a/base/test/test_file_util_win.cc b/base/test/test_file_util_win.cc
index 1f20740..0159d2e 100644
--- a/base/test/test_file_util_win.cc
+++ b/base/test/test_file_util_win.cc
@@ -220,5 +220,8 @@ bool HasInternetZoneIdentifier(const FilePath& full_path) {
std::wstring FilePathAsWString(const FilePath& path) {
return path.value();
}
+FilePath WStringAsFilePath(const std::wstring& path) {
+ return FilePath(path);
+}
} // namespace file_util
diff --git a/base/test/test_suite.cc b/base/test/test_suite.cc
index 42b5b90..d952dc9 100644
--- a/base/test/test_suite.cc
+++ b/base/test/test_suite.cc
@@ -14,10 +14,9 @@
#include "base/i18n/icu_util.h"
#include "base/logging.h"
#include "base/mac/scoped_nsautorelease_pool.h"
-#include "base/nss_util.h"
+#include "base/memory/scoped_ptr.h"
#include "base/path_service.h"
#include "base/process_util.h"
-#include "base/scoped_ptr.h"
#include "base/test/multiprocess_test.h"
#include "base/test/test_timeouts.h"
#include "base/time.h"
@@ -214,14 +213,6 @@ void TestSuite::Initialize() {
icu_util::Initialize();
-#if defined(USE_NSS)
- // Trying to repeatedly initialize and cleanup NSS and NSPR may result in
- // a deadlock. Such repeated initialization will happen when using test
- // isolation. Prevent problems by initializing NSS here, so that the cleanup
- // will be done only on process exit.
- base::EnsureNSSInit();
-#endif // defined(USE_NSS)
-
CatchMaybeTests();
TestTimeouts::Initialize();
diff --git a/base/test/test_switches.cc b/base/test/test_switches.cc
index 991f4f3..d4491ee 100644
--- a/base/test/test_switches.cc
+++ b/base/test/test_switches.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -13,6 +13,5 @@ const char switches::kTestLargeTimeout[] = "test-large-timeout";
const char switches::kTestTinyTimeout[] = "test-tiny-timeout";
const char switches::kUiTestActionTimeout[] = "ui-test-action-timeout";
const char switches::kUiTestActionMaxTimeout[] = "ui-test-action-max-timeout";
-const char switches::kUiTestCommandExecutionTimeout[] = "ui-test-timeout";
const char switches::kUiTestTerminateTimeout[] = "ui-test-terminate-timeout";
const char switches::kUiTestTimeout[] = "test-timeout";
diff --git a/base/test/test_switches.h b/base/test/test_switches.h
index 44ebd23..81891cb 100644
--- a/base/test/test_switches.h
+++ b/base/test/test_switches.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -14,7 +14,6 @@ extern const char kTestLargeTimeout[];
extern const char kTestTinyTimeout[];
extern const char kUiTestActionTimeout[];
extern const char kUiTestActionMaxTimeout[];
-extern const char kUiTestCommandExecutionTimeout[];
extern const char kUiTestTerminateTimeout[];
extern const char kUiTestTimeout[];
diff --git a/base/test/test_timeouts.cc b/base/test/test_timeouts.cc
index 20cd8a9..1d86b2c 100644
--- a/base/test/test_timeouts.cc
+++ b/base/test/test_timeouts.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -44,14 +44,11 @@ bool TestTimeouts::initialized_ = false;
// static
int TestTimeouts::tiny_timeout_ms_ = 100;
int TestTimeouts::action_timeout_ms_ = 2000;
-int TestTimeouts::action_max_timeout_ms_ = 20000;
+int TestTimeouts::action_max_timeout_ms_ = 25000;
int TestTimeouts::large_test_timeout_ms_ = 3 * 60 * 1000;
int TestTimeouts::huge_test_timeout_ms_ = 10 * 60 * 1000;
// static
-int TestTimeouts::command_execution_timeout_ms_ = 25000;
-
-// static
int TestTimeouts::wait_for_terminate_timeout_ms_ = 15000;
// static
@@ -83,8 +80,6 @@ void TestTimeouts::Initialize() {
CHECK(action_max_timeout_ms_ <= large_test_timeout_ms_);
CHECK(large_test_timeout_ms_ <= huge_test_timeout_ms_);
- InitializeTimeout(switches::kUiTestCommandExecutionTimeout,
- &command_execution_timeout_ms_);
InitializeTimeout(switches::kUiTestTerminateTimeout,
&wait_for_terminate_timeout_ms_);
diff --git a/base/test/test_timeouts.h b/base/test/test_timeouts.h
index f4cb1ff..64df11a 100644
--- a/base/test/test_timeouts.h
+++ b/base/test/test_timeouts.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -35,12 +35,6 @@ class TestTimeouts {
// Do not use multiple times in a single test.
static int huge_test_timeout_ms() { return huge_test_timeout_ms_; }
- // Timeout to use for AutomationProxy. Do not use in other places.
- // TODO(phajdan.jr): Remove command_execution_timeout_ms.
- static int command_execution_timeout_ms() {
- return command_execution_timeout_ms_;
- }
-
// Timeout to wait for a process to terminate.
static int wait_for_terminate_timeout_ms() {
return wait_for_terminate_timeout_ms_;
@@ -60,7 +54,6 @@ class TestTimeouts {
static int action_max_timeout_ms_;
static int large_test_timeout_ms_;
static int huge_test_timeout_ms_;
- static int command_execution_timeout_ms_;
static int wait_for_terminate_timeout_ms_;
static int live_operation_timeout_ms_;
diff --git a/base/third_party/nspr/prcpucfg.h b/base/third_party/nspr/prcpucfg.h
index 59e2cdf..b5f0497 100644
--- a/base/third_party/nspr/prcpucfg.h
+++ b/base/third_party/nspr/prcpucfg.h
@@ -34,7 +34,13 @@
#include "base/third_party/nspr/prcpucfg_win.h"
#elif defined(__APPLE__)
#include "base/third_party/nspr/prcpucfg_mac.h"
+<<<<<<< HEAD
#elif defined(__linux__) || defined(__native_client__) || defined(ANDROID)
+=======
+#elif defined(__native_client__)
+#include "base/third_party/nspr/prcpucfg_nacl.h"
+#elif defined(__linux__)
+>>>>>>> chromium.org at r12.0.742.93
#include "base/third_party/nspr/prcpucfg_linux.h"
#elif defined(__FreeBSD__)
#include "base/third_party/nspr/prcpucfg_freebsd.h"
diff --git a/base/third_party/nspr/prcpucfg_mac.h b/base/third_party/nspr/prcpucfg_mac.h
index dc7e0e0..60bea8e 100644
--- a/base/third_party/nspr/prcpucfg_mac.h
+++ b/base/third_party/nspr/prcpucfg_mac.h
@@ -44,7 +44,7 @@
#define PR_AF_INET6 30 /* same as AF_INET6 */
-#if defined(i386)
+#ifdef __LITTLE_ENDIAN__
#undef IS_BIG_ENDIAN
#define IS_LITTLE_ENDIAN 1
#else
@@ -52,10 +52,60 @@
#define IS_BIG_ENDIAN 1
#endif
+#ifdef __x86_64__
+#define IS_64
+#endif
+
+#ifndef HAVE_LONG_LONG
#define HAVE_LONG_LONG
+#endif
#undef HAVE_ALIGNED_DOUBLES
#define HAVE_ALIGNED_LONGLONGS 1
+#ifdef IS_64
+
+#define PR_BYTES_PER_BYTE 1
+#define PR_BYTES_PER_SHORT 2
+#define PR_BYTES_PER_INT 4
+#define PR_BYTES_PER_INT64 8
+#define PR_BYTES_PER_LONG 8
+#define PR_BYTES_PER_FLOAT 4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD 8
+#define PR_BYTES_PER_DWORD 8
+
+#define PR_BITS_PER_BYTE 8
+#define PR_BITS_PER_SHORT 16
+#define PR_BITS_PER_INT 32
+#define PR_BITS_PER_INT64 64
+#define PR_BITS_PER_LONG 64
+#define PR_BITS_PER_FLOAT 32
+#define PR_BITS_PER_DOUBLE 64
+#define PR_BITS_PER_WORD 64
+#define PR_BITS_PER_DWORD 64
+
+#define PR_BITS_PER_BYTE_LOG2 3
+#define PR_BITS_PER_SHORT_LOG2 4
+#define PR_BITS_PER_INT_LOG2 5
+#define PR_BITS_PER_INT64_LOG2 6
+#define PR_BITS_PER_LONG_LOG2 6
+#define PR_BITS_PER_FLOAT_LOG2 5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2 6
+#define PR_BITS_PER_DWORD_LOG2 6
+
+#define PR_ALIGN_OF_SHORT 2
+#define PR_ALIGN_OF_INT 4
+#define PR_ALIGN_OF_LONG 8
+#define PR_ALIGN_OF_INT64 8
+#define PR_ALIGN_OF_FLOAT 4
+#define PR_ALIGN_OF_DOUBLE 8
+#define PR_ALIGN_OF_POINTER 8
+#define PR_ALIGN_OF_WORD 8
+#define PR_ALIGN_OF_DWORD 8
+
+#else /* IS_64 */
+
#define PR_BYTES_PER_BYTE 1
#define PR_BYTES_PER_SHORT 2
#define PR_BYTES_PER_INT 4
@@ -96,6 +146,8 @@
#define PR_ALIGN_OF_POINTER 4
#define PR_ALIGN_OF_WORD 4
+#endif /* IS_64 */
+
#ifndef NO_NSPR_10_SUPPORT
#define BYTES_PER_BYTE PR_BYTES_PER_BYTE
diff --git a/base/third_party/nspr/prcpucfg_nacl.h b/base/third_party/nspr/prcpucfg_nacl.h
new file mode 100644
index 0000000..d8602d3
--- /dev/null
+++ b/base/third_party/nspr/prcpucfg_nacl.h
@@ -0,0 +1,246 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nspr_cpucfg___
+#define nspr_cpucfg___
+
+#ifndef XP_UNIX
+#define XP_UNIX
+#endif
+
+#ifndef LINUX
+#define LINUX
+#endif
+
+#define PR_AF_INET6 10 /* same as AF_INET6 */
+
+#if defined(__x86_64__)
+
+#define IS_LITTLE_ENDIAN 1
+#undef IS_BIG_ENDIAN
+#define IS_64
+
+#define PR_BYTES_PER_BYTE 1
+#define PR_BYTES_PER_SHORT 2
+#define PR_BYTES_PER_INT 4
+#define PR_BYTES_PER_INT64 8
+#define PR_BYTES_PER_LONG 4
+#define PR_BYTES_PER_FLOAT 4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD 8
+#define PR_BYTES_PER_DWORD 8
+
+#define PR_BITS_PER_BYTE 8
+#define PR_BITS_PER_SHORT 16
+#define PR_BITS_PER_INT 32
+#define PR_BITS_PER_INT64 64
+#define PR_BITS_PER_LONG 32
+#define PR_BITS_PER_FLOAT 32
+#define PR_BITS_PER_DOUBLE 64
+#define PR_BITS_PER_WORD 64
+
+#define PR_BITS_PER_BYTE_LOG2 3
+#define PR_BITS_PER_SHORT_LOG2 4
+#define PR_BITS_PER_INT_LOG2 5
+#define PR_BITS_PER_INT64_LOG2 6
+#define PR_BITS_PER_LONG_LOG2 5
+#define PR_BITS_PER_FLOAT_LOG2 5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2 6
+
+#define PR_ALIGN_OF_SHORT 2
+#define PR_ALIGN_OF_INT 4
+#define PR_ALIGN_OF_LONG 4
+#define PR_ALIGN_OF_INT64 8
+#define PR_ALIGN_OF_FLOAT 4
+#define PR_ALIGN_OF_DOUBLE 8
+#define PR_ALIGN_OF_POINTER 8
+#define PR_ALIGN_OF_WORD 8
+
+#define PR_BYTES_PER_WORD_LOG2 3
+#define PR_BYTES_PER_DWORD_LOG2 3
+
+#elif defined(__i386__)
+
+#define IS_LITTLE_ENDIAN 1
+#undef IS_BIG_ENDIAN
+
+#define PR_BYTES_PER_BYTE 1
+#define PR_BYTES_PER_SHORT 2
+#define PR_BYTES_PER_INT 4
+#define PR_BYTES_PER_INT64 8
+#define PR_BYTES_PER_LONG 4
+#define PR_BYTES_PER_FLOAT 4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD 4
+#define PR_BYTES_PER_DWORD 8
+
+#define PR_BITS_PER_BYTE 8
+#define PR_BITS_PER_SHORT 16
+#define PR_BITS_PER_INT 32
+#define PR_BITS_PER_INT64 64
+#define PR_BITS_PER_LONG 32
+#define PR_BITS_PER_FLOAT 32
+#define PR_BITS_PER_DOUBLE 64
+#define PR_BITS_PER_WORD 32
+
+#define PR_BITS_PER_BYTE_LOG2 3
+#define PR_BITS_PER_SHORT_LOG2 4
+#define PR_BITS_PER_INT_LOG2 5
+#define PR_BITS_PER_INT64_LOG2 6
+#define PR_BITS_PER_LONG_LOG2 5
+#define PR_BITS_PER_FLOAT_LOG2 5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2 5
+
+#define PR_ALIGN_OF_SHORT 2
+#define PR_ALIGN_OF_INT 4
+#define PR_ALIGN_OF_LONG 4
+#define PR_ALIGN_OF_INT64 4
+#define PR_ALIGN_OF_FLOAT 4
+#define PR_ALIGN_OF_DOUBLE 4
+#define PR_ALIGN_OF_POINTER 4
+#define PR_ALIGN_OF_WORD 4
+
+#define PR_BYTES_PER_WORD_LOG2 2
+#define PR_BYTES_PER_DWORD_LOG2 3
+
+#elif defined(__arm__)
+
+#define IS_LITTLE_ENDIAN 1
+#undef IS_BIG_ENDIAN
+
+#define PR_BYTES_PER_BYTE 1
+#define PR_BYTES_PER_SHORT 2
+#define PR_BYTES_PER_INT 4
+#define PR_BYTES_PER_INT64 8
+#define PR_BYTES_PER_LONG 4
+#define PR_BYTES_PER_FLOAT 4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD 4
+#define PR_BYTES_PER_DWORD 8
+
+#define PR_BITS_PER_BYTE 8
+#define PR_BITS_PER_SHORT 16
+#define PR_BITS_PER_INT 32
+#define PR_BITS_PER_INT64 64
+#define PR_BITS_PER_LONG 32
+#define PR_BITS_PER_FLOAT 32
+#define PR_BITS_PER_DOUBLE 64
+#define PR_BITS_PER_WORD 32
+
+#define PR_BITS_PER_BYTE_LOG2 3
+#define PR_BITS_PER_SHORT_LOG2 4
+#define PR_BITS_PER_INT_LOG2 5
+#define PR_BITS_PER_INT64_LOG2 6
+#define PR_BITS_PER_LONG_LOG2 5
+#define PR_BITS_PER_FLOAT_LOG2 5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2 5
+
+#define PR_ALIGN_OF_SHORT 2
+#define PR_ALIGN_OF_INT 4
+#define PR_ALIGN_OF_LONG 4
+#define PR_ALIGN_OF_INT64 4
+#define PR_ALIGN_OF_FLOAT 4
+#define PR_ALIGN_OF_DOUBLE 4
+#define PR_ALIGN_OF_POINTER 4
+#define PR_ALIGN_OF_WORD 4
+
+#define PR_BYTES_PER_WORD_LOG2 2
+#define PR_BYTES_PER_DWORD_LOG2 3
+
+#else
+
+#error "Unknown CPU architecture"
+
+#endif
+
+#define HAVE_LONG_LONG
+#if PR_ALIGN_OF_DOUBLE == 8
+#define HAVE_ALIGNED_DOUBLES
+#endif
+#if PR_ALIGN_OF_INT64 == 8
+#define HAVE_ALIGNED_LONGLONGS
+#endif
+
+#ifndef NO_NSPR_10_SUPPORT
+
+#define BYTES_PER_BYTE PR_BYTES_PER_BYTE
+#define BYTES_PER_SHORT PR_BYTES_PER_SHORT
+#define BYTES_PER_INT PR_BYTES_PER_INT
+#define BYTES_PER_INT64 PR_BYTES_PER_INT64
+#define BYTES_PER_LONG PR_BYTES_PER_LONG
+#define BYTES_PER_FLOAT PR_BYTES_PER_FLOAT
+#define BYTES_PER_DOUBLE PR_BYTES_PER_DOUBLE
+#define BYTES_PER_WORD PR_BYTES_PER_WORD
+#define BYTES_PER_DWORD PR_BYTES_PER_DWORD
+
+#define BITS_PER_BYTE PR_BITS_PER_BYTE
+#define BITS_PER_SHORT PR_BITS_PER_SHORT
+#define BITS_PER_INT PR_BITS_PER_INT
+#define BITS_PER_INT64 PR_BITS_PER_INT64
+#define BITS_PER_LONG PR_BITS_PER_LONG
+#define BITS_PER_FLOAT PR_BITS_PER_FLOAT
+#define BITS_PER_DOUBLE PR_BITS_PER_DOUBLE
+#define BITS_PER_WORD PR_BITS_PER_WORD
+
+#define BITS_PER_BYTE_LOG2 PR_BITS_PER_BYTE_LOG2
+#define BITS_PER_SHORT_LOG2 PR_BITS_PER_SHORT_LOG2
+#define BITS_PER_INT_LOG2 PR_BITS_PER_INT_LOG2
+#define BITS_PER_INT64_LOG2 PR_BITS_PER_INT64_LOG2
+#define BITS_PER_LONG_LOG2 PR_BITS_PER_LONG_LOG2
+#define BITS_PER_FLOAT_LOG2 PR_BITS_PER_FLOAT_LOG2
+#define BITS_PER_DOUBLE_LOG2 PR_BITS_PER_DOUBLE_LOG2
+#define BITS_PER_WORD_LOG2 PR_BITS_PER_WORD_LOG2
+
+#define ALIGN_OF_SHORT PR_ALIGN_OF_SHORT
+#define ALIGN_OF_INT PR_ALIGN_OF_INT
+#define ALIGN_OF_LONG PR_ALIGN_OF_LONG
+#define ALIGN_OF_INT64 PR_ALIGN_OF_INT64
+#define ALIGN_OF_FLOAT PR_ALIGN_OF_FLOAT
+#define ALIGN_OF_DOUBLE PR_ALIGN_OF_DOUBLE
+#define ALIGN_OF_POINTER PR_ALIGN_OF_POINTER
+#define ALIGN_OF_WORD PR_ALIGN_OF_WORD
+
+#define BYTES_PER_WORD_LOG2 PR_BYTES_PER_WORD_LOG2
+#define BYTES_PER_DWORD_LOG2 PR_BYTES_PER_DWORD_LOG2
+#define WORDS_PER_DWORD_LOG2 PR_WORDS_PER_DWORD_LOG2
+
+#endif /* NO_NSPR_10_SUPPORT */
+
+#endif /* nspr_cpucfg___ */
diff --git a/base/third_party/nspr/prtime.cc b/base/third_party/nspr/prtime.cc
index 65f93ee..f1fcf26 100644
--- a/base/third_party/nspr/prtime.cc
+++ b/base/third_party/nspr/prtime.cc
@@ -1,4 +1,4 @@
-/* Portions are Copyright (C) 2007 Google Inc */
+/* Portions are Copyright (C) 2011 Google Inc */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
@@ -63,6 +63,7 @@
* 3. prlong.h
*/
+#include "base/logging.h"
#include "base/third_party/nspr/prtime.h"
#include "build/build_config.h"
diff --git a/base/third_party/nspr/prtime.h b/base/third_party/nspr/prtime.h
index dd75cbc..a207021 100644
--- a/base/third_party/nspr/prtime.h
+++ b/base/third_party/nspr/prtime.h
@@ -1,4 +1,4 @@
-/* Portions are Copyright (C) 2007 Google Inc */
+/* Portions are Copyright (C) 2011 Google Inc */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
@@ -52,7 +52,7 @@
#ifndef BASE_PRTIME_H__
#define BASE_PRTIME_H__
-#include "base/logging.h"
+#include "base/base_api.h"
#include "base/third_party/nspr/prtypes.h"
#define PR_ASSERT DCHECK
@@ -225,7 +225,12 @@ NSPR_API(PRTimeParameters) PR_GMTParameters(const PRExplodedTime *gmt);
* the time string which you are parsing.
*/
-NSPR_API(PRStatus) PR_ParseTimeString (
+/*
+ * This is the only funtion that should be called from outside base, and only
+ * from the unit test.
+ */
+
+BASE_API PRStatus PR_ParseTimeString (
const char *string,
PRBool default_to_gmt,
PRTime *result);
diff --git a/base/third_party/nspr/prtypes.h b/base/third_party/nspr/prtypes.h
index 3453144..630df81 100644
--- a/base/third_party/nspr/prtypes.h
+++ b/base/third_party/nspr/prtypes.h
@@ -135,55 +135,6 @@
#define PR_CALLBACK_DECL
#define PR_STATIC_CALLBACK(__x) static __x
-#elif defined(WIN16)
-
-#define PR_CALLBACK_DECL __cdecl
-
-#if defined(_WINDLL)
-#define PR_EXPORT(__type) extern __type _cdecl _export _loadds
-#define PR_IMPORT(__type) extern __type _cdecl _export _loadds
-#define PR_EXPORT_DATA(__type) extern __type _export
-#define PR_IMPORT_DATA(__type) extern __type _export
-
-#define PR_EXTERN(__type) extern __type _cdecl _export _loadds
-#define PR_IMPLEMENT(__type) __type _cdecl _export _loadds
-#define PR_EXTERN_DATA(__type) extern __type _export
-#define PR_IMPLEMENT_DATA(__type) __type _export
-
-#define PR_CALLBACK __cdecl __loadds
-#define PR_STATIC_CALLBACK(__x) static __x PR_CALLBACK
-
-#else /* this must be .EXE */
-#define PR_EXPORT(__type) extern __type _cdecl _export
-#define PR_IMPORT(__type) extern __type _cdecl _export
-#define PR_EXPORT_DATA(__type) extern __type _export
-#define PR_IMPORT_DATA(__type) extern __type _export
-
-#define PR_EXTERN(__type) extern __type _cdecl _export
-#define PR_IMPLEMENT(__type) __type _cdecl _export
-#define PR_EXTERN_DATA(__type) extern __type _export
-#define PR_IMPLEMENT_DATA(__type) __type _export
-
-#define PR_CALLBACK __cdecl __loadds
-#define PR_STATIC_CALLBACK(__x) __x PR_CALLBACK
-#endif /* _WINDLL */
-
-#elif defined(XP_MAC)
-
-#define PR_EXPORT(__type) extern __declspec(export) __type
-#define PR_EXPORT_DATA(__type) extern __declspec(export) __type
-#define PR_IMPORT(__type) extern __declspec(export) __type
-#define PR_IMPORT_DATA(__type) extern __declspec(export) __type
-
-#define PR_EXTERN(__type) extern __declspec(export) __type
-#define PR_IMPLEMENT(__type) __declspec(export) __type
-#define PR_EXTERN_DATA(__type) extern __declspec(export) __type
-#define PR_IMPLEMENT_DATA(__type) __declspec(export) __type
-
-#define PR_CALLBACK
-#define PR_CALLBACK_DECL
-#define PR_STATIC_CALLBACK(__x) static __x
-
#elif defined(XP_OS2) && defined(__declspec)
#define PR_EXPORT(__type) extern __declspec(dllexport) __type
@@ -200,20 +151,26 @@
#define PR_CALLBACK_DECL
#define PR_STATIC_CALLBACK(__x) static __x
-#elif defined(XP_OS2_VACPP)
+#elif defined(SYMBIAN)
-#define PR_EXPORT(__type) extern __type
-#define PR_EXPORT_DATA(__type) extern __type
-#define PR_IMPORT(__type) extern __type
-#define PR_IMPORT_DATA(__type) extern __type
+#define PR_EXPORT(__type) extern __declspec(dllexport) __type
+#define PR_EXPORT_DATA(__type) extern __declspec(dllexport) __type
+#ifdef __WINS__
+#define PR_IMPORT(__type) extern __declspec(dllexport) __type
+#define PR_IMPORT_DATA(__type) extern __declspec(dllexport) __type
+#else
+#define PR_IMPORT(__type) extern __declspec(dllimport) __type
+#define PR_IMPORT_DATA(__type) extern __declspec(dllimport) __type
+#endif
#define PR_EXTERN(__type) extern __type
#define PR_IMPLEMENT(__type) __type
#define PR_EXTERN_DATA(__type) extern __type
#define PR_IMPLEMENT_DATA(__type) __type
-#define PR_CALLBACK _Optlink
+
+#define PR_CALLBACK
#define PR_CALLBACK_DECL
-#define PR_STATIC_CALLBACK(__x) static __x PR_CALLBACK
+#define PR_STATIC_CALLBACK(__x) static __x
#else /* Unix */
@@ -301,7 +258,7 @@ PR_BEGIN_EXTERN_C
** PRInt8
** DESCRIPTION:
** The int8 types are known to be 8 bits each. There is no type that
-** is equivalent to a plain "char".
+** is equivalent to a plain "char".
************************************************************************/
#if PR_BYTES_PER_BYTE == 1
typedef unsigned char PRUint8;
@@ -340,7 +297,7 @@ typedef signed char PRInt8;
** TYPES: PRUint16
** PRInt16
** DESCRIPTION:
-** The int16 types are known to be 16 bits each.
+** The int16 types are known to be 16 bits each.
************************************************************************/
#if PR_BYTES_PER_SHORT == 2
typedef unsigned short PRUint16;
@@ -365,7 +322,7 @@ typedef short PRInt16;
** TYPES: PRUint32
** PRInt32
** DESCRIPTION:
-** The int32 types are known to be 32 bits each.
+** The int32 types are known to be 32 bits each.
************************************************************************/
#if PR_BYTES_PER_INT == 4
typedef unsigned int PRUint32;
@@ -404,12 +361,15 @@ typedef long PRInt32;
** the LL_ macros (see prlong.h).
************************************************************************/
#ifdef HAVE_LONG_LONG
-#if PR_BYTES_PER_LONG == 8
+/* Keep this in sync with prlong.h. */
+/*
+ * On 64-bit Mac OS X, uint64 needs to be defined as unsigned long long to
+ * match uint64_t, otherwise our uint64 typedef conflicts with the uint64
+ * typedef in cssmconfig.h, which CoreServices.h includes indirectly.
+ */
+#if PR_BYTES_PER_LONG == 8 && !defined(__APPLE__)
typedef long PRInt64;
typedef unsigned long PRUint64;
-#elif defined(WIN16)
-typedef __int64 PRInt64;
-typedef unsigned __int64 PRUint64;
#elif defined(WIN32) && !defined(__GNUC__)
typedef __int64 PRInt64;
typedef unsigned __int64 PRUint64;
@@ -435,7 +395,7 @@ typedef PRInt64 PRUint64;
** The PRIntn types are most appropriate for automatic variables. They are
** guaranteed to be at least 16 bits, though various architectures may
** define them to be wider (e.g., 32 or even 64 bits). These types are
-** never valid for fields of a structure.
+** never valid for fields of a structure.
************************************************************************/
#if PR_BYTES_PER_INT >= 2
typedef int PRIntn;
@@ -447,14 +407,14 @@ typedef unsigned int PRUintn;
/************************************************************************
** TYPES: PRFloat64
** DESCRIPTION:
-** NSPR's floating point type is always 64 bits.
+** NSPR's floating point type is always 64 bits.
************************************************************************/
typedef double PRFloat64;
/************************************************************************
** TYPES: PRSize
** DESCRIPTION:
-** A type for representing the size of objects.
+** A type for representing the size of objects.
************************************************************************/
typedef size_t PRSize;
@@ -462,7 +422,7 @@ typedef size_t PRSize;
/************************************************************************
** TYPES: PROffset32, PROffset64
** DESCRIPTION:
-** A type for representing byte offsets from some location.
+** A type for representing byte offsets from some location.
************************************************************************/
typedef PRInt32 PROffset32;
typedef PRInt64 PROffset64;
@@ -471,7 +431,7 @@ typedef PRInt64 PROffset64;
** TYPES: PRPtrDiff
** DESCRIPTION:
** A type for pointer difference. Variables of this type are suitable
-** for storing a pointer or pointer subtraction.
+** for storing a pointer or pointer subtraction.
************************************************************************/
typedef ptrdiff_t PRPtrdiff;
@@ -479,10 +439,10 @@ typedef ptrdiff_t PRPtrdiff;
** TYPES: PRUptrdiff
** DESCRIPTION:
** A type for pointer difference. Variables of this type are suitable
-** for storing a pointer or pointer sutraction.
+** for storing a pointer or pointer sutraction.
************************************************************************/
#ifdef _WIN64
-typedef unsigned __int64 PRUptrdiff;
+typedef PRUint64 PRUptrdiff;
#else
typedef unsigned long PRUptrdiff;
#endif
@@ -493,7 +453,7 @@ typedef unsigned long PRUptrdiff;
** Use PRBool for variables and parameter types. Use PR_FALSE and PR_TRUE
** for clarity of target type in assignments and actual arguments. Use
** 'if (bool)', 'while (!bool)', '(bool) ? x : y' etc., to test booleans
-** just as you would C int-valued conditions.
+** just as you would C int-valued conditions.
************************************************************************/
typedef PRIntn PRBool;
#define PR_TRUE 1
@@ -508,14 +468,14 @@ typedef PRIntn PRBool;
typedef PRUint8 PRPackedBool;
/*
-** Status code used by some routines that have a single point of failure or
+** Status code used by some routines that have a single point of failure or
** special status return.
*/
typedef enum { PR_FAILURE = -1, PR_SUCCESS = 0 } PRStatus;
#ifndef __PRUNICHAR__
#define __PRUNICHAR__
-#if defined(WIN32) || defined(XP_MAC)
+#ifdef WIN32
typedef wchar_t PRUnichar;
#else
typedef PRUint16 PRUnichar;
@@ -534,8 +494,8 @@ typedef PRUint16 PRUnichar;
** http://java.sun.com/docs/books/vmspec/index.html.)
*/
#ifdef _WIN64
-typedef __int64 PRWord;
-typedef unsigned __int64 PRUword;
+typedef PRInt64 PRWord;
+typedef PRUint64 PRUword;
#else
typedef long PRWord;
typedef unsigned long PRUword;
@@ -580,6 +540,14 @@ typedef unsigned long PRUword;
/********* ????????????? End Fix me ?????????????????????????????? *****/
#endif /* NO_NSPR_10_SUPPORT */
+/*
+** Compile-time assert. "condition" must be a constant expression.
+** The macro can be used only in places where an "extern" declaration is
+** allowed.
+*/
+#define PR_STATIC_ASSERT(condition) \
+ extern void pr_static_assert(int arg[(condition) ? 1 : -1])
+
PR_END_EXTERN_C
#if !defined(NO_NSPR_10_SUPPORT)
diff --git a/base/threading/non_thread_safe.h b/base/threading/non_thread_safe.h
index bc3be3c..e4a1c07 100644
--- a/base/threading/non_thread_safe.h
+++ b/base/threading/non_thread_safe.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
diff --git a/base/threading/non_thread_safe_impl.h b/base/threading/non_thread_safe_impl.h
index 12925f1..ab0999a 100644
--- a/base/threading/non_thread_safe_impl.h
+++ b/base/threading/non_thread_safe_impl.h
@@ -6,6 +6,7 @@
#define BASE_THREADING_NON_THREAD_SAFE_IMPL_H_
#pragma once
+#include "base/base_api.h"
#include "base/threading/thread_checker_impl.h"
namespace base {
@@ -16,7 +17,7 @@ namespace base {
//
// Note: You should almost always use the NonThreadSafe class to get
// the right version of the class for your build configuration.
-class NonThreadSafeImpl {
+class BASE_API NonThreadSafeImpl {
public:
~NonThreadSafeImpl();
diff --git a/base/threading/non_thread_safe_unittest.cc b/base/threading/non_thread_safe_unittest.cc
index b79a4f4..01efe28 100644
--- a/base/threading/non_thread_safe_unittest.cc
+++ b/base/threading/non_thread_safe_unittest.cc
@@ -1,10 +1,10 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
#include "base/basictypes.h"
#include "base/logging.h"
-#include "base/scoped_ptr.h"
+#include "base/memory/scoped_ptr.h"
#include "base/threading/non_thread_safe.h"
#include "base/threading/simple_thread.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/base/threading/platform_thread.h b/base/threading/platform_thread.h
index 0a3c75d..40d445f 100644
--- a/base/threading/platform_thread.h
+++ b/base/threading/platform_thread.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -10,6 +10,7 @@
#define BASE_THREADING_PLATFORM_THREAD_H_
#pragma once
+#include "base/base_api.h"
#include "base/basictypes.h"
#include "build/build_config.h"
@@ -47,11 +48,11 @@ typedef pid_t PlatformThreadId;
const PlatformThreadId kInvalidThreadId = 0;
// A namespace for low-level thread functions.
-class PlatformThread {
+class BASE_API PlatformThread {
public:
// Implement this interface to run code on a background thread. Your
// ThreadMain method will be called on the newly created thread.
- class Delegate {
+ class BASE_API Delegate {
public:
virtual ~Delegate() {}
virtual void ThreadMain() = 0;
diff --git a/base/threading/platform_thread_posix.cc b/base/threading/platform_thread_posix.cc
index 103145a..e880222 100644
--- a/base/threading/platform_thread_posix.cc
+++ b/base/threading/platform_thread_posix.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -8,8 +8,8 @@
#include <sched.h>
#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
#include "base/safe_strerror_posix.h"
-#include "base/scoped_ptr.h"
#include "base/threading/thread_restrictions.h"
#if defined(OS_MACOSX)
diff --git a/base/threading/simple_thread.h b/base/threading/simple_thread.h
index 1631336..f1b644b 100644
--- a/base/threading/simple_thread.h
+++ b/base/threading/simple_thread.h
@@ -45,6 +45,7 @@
#include <queue>
#include <vector>
+#include "base/base_api.h"
#include "base/basictypes.h"
#include "base/threading/platform_thread.h"
#include "base/synchronization/lock.h"
@@ -54,9 +55,9 @@ namespace base {
// This is the base SimpleThread. You can derive from it and implement the
// virtual Run method, or you can use the DelegateSimpleThread interface.
-class SimpleThread : public PlatformThread::Delegate {
+class BASE_API SimpleThread : public PlatformThread::Delegate {
public:
- class Options {
+ class BASE_API Options {
public:
Options() : stack_size_(0) { }
~Options() { }
@@ -113,9 +114,9 @@ class SimpleThread : public PlatformThread::Delegate {
bool joined_; // True if Join has been called.
};
-class DelegateSimpleThread : public SimpleThread {
+class BASE_API DelegateSimpleThread : public SimpleThread {
public:
- class Delegate {
+ class BASE_API Delegate {
public:
Delegate() { }
virtual ~Delegate() { }
@@ -143,7 +144,8 @@ class DelegateSimpleThread : public SimpleThread {
// JoinAll() will make sure that all outstanding work is processed, and wait
// for everything to finish. You can reuse a pool, so you can call Start()
// again after you've called JoinAll().
-class DelegateSimpleThreadPool : public DelegateSimpleThread::Delegate {
+class BASE_API DelegateSimpleThreadPool
+ : public DelegateSimpleThread::Delegate {
public:
typedef DelegateSimpleThread::Delegate Delegate;
diff --git a/base/threading/thread.h b/base/threading/thread.h
index 379615d..034cb7d 100644
--- a/base/threading/thread.h
+++ b/base/threading/thread.h
@@ -8,6 +8,7 @@
#include <string>
+#include "base/base_api.h"
#include "base/message_loop.h"
#include "base/message_loop_proxy.h"
#include "base/threading/platform_thread.h"
@@ -25,7 +26,7 @@ namespace base {
// (1) Thread::CleanUp()
// (2) MessageLoop::~MessageLoop
// (3.b) MessageLoop::DestructionObserver::WillDestroyCurrentMessageLoop
-class Thread : PlatformThread::Delegate {
+class BASE_API Thread : PlatformThread::Delegate {
public:
struct Options {
Options() : message_loop_type(MessageLoop::TYPE_DEFAULT), stack_size(0) {}
diff --git a/base/threading/thread_checker_impl.h b/base/threading/thread_checker_impl.h
index 6d41fdc..02ecebf 100644
--- a/base/threading/thread_checker_impl.h
+++ b/base/threading/thread_checker_impl.h
@@ -6,6 +6,7 @@
#define BASE_THREADING_THREAD_CHECKER_IMPL_H_
#pragma once
+#include "base/base_api.h"
#include "base/synchronization/lock.h"
#include "base/threading/platform_thread.h"
@@ -17,7 +18,7 @@ namespace base {
//
// Note: You should almost always use the ThreadChecker class to get the
// right version for your build configuration.
-class ThreadCheckerImpl {
+class BASE_API ThreadCheckerImpl {
public:
ThreadCheckerImpl();
~ThreadCheckerImpl();
diff --git a/base/threading/thread_checker_unittest.cc b/base/threading/thread_checker_unittest.cc
index 9a22a8e..2808048 100644
--- a/base/threading/thread_checker_unittest.cc
+++ b/base/threading/thread_checker_unittest.cc
@@ -1,10 +1,10 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
#include "base/basictypes.h"
#include "base/logging.h"
-#include "base/scoped_ptr.h"
+#include "base/memory/scoped_ptr.h"
#include "base/threading/thread_checker.h"
#include "base/threading/simple_thread.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/base/threading/thread_collision_warner.h b/base/threading/thread_collision_warner.h
index 17ed5a4..b26568d 100644
--- a/base/threading/thread_collision_warner.h
+++ b/base/threading/thread_collision_warner.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -8,6 +8,7 @@
#include <memory>
+#include "base/base_api.h"
#include "base/atomicops.h"
// A helper class alongside macros to be used to verify assumptions about thread
@@ -130,17 +131,17 @@ namespace base {
// AsserterBase is the interfaces and DCheckAsserter is the default asserter
// used. During the unit tests is used another class that doesn't "DCHECK"
// in case of collision (check thread_collision_warner_unittests.cc)
-struct AsserterBase {
+struct BASE_API AsserterBase {
virtual ~AsserterBase() {}
virtual void warn() = 0;
};
-struct DCheckAsserter : public AsserterBase {
+struct BASE_API DCheckAsserter : public AsserterBase {
virtual ~DCheckAsserter() {}
virtual void warn();
};
-class ThreadCollisionWarner {
+class BASE_API ThreadCollisionWarner {
public:
// The parameter asserter is there only for test purpose
ThreadCollisionWarner(AsserterBase* asserter = new DCheckAsserter())
@@ -157,7 +158,7 @@ class ThreadCollisionWarner {
// it doesn't leave the critical section, as opposed to ScopedCheck,
// because the critical section being pinned is allowed to be used only
// from one thread
- class Check {
+ class BASE_API Check {
public:
explicit Check(ThreadCollisionWarner* warner)
: warner_(warner) {
@@ -174,7 +175,7 @@ class ThreadCollisionWarner {
// This class is meant to be used through the macro
// DFAKE_SCOPED_LOCK
- class ScopedCheck {
+ class BASE_API ScopedCheck {
public:
explicit ScopedCheck(ThreadCollisionWarner* warner)
: warner_(warner) {
@@ -193,7 +194,7 @@ class ThreadCollisionWarner {
// This class is meant to be used through the macro
// DFAKE_SCOPED_RECURSIVE_LOCK
- class ScopedRecursiveCheck {
+ class BASE_API ScopedRecursiveCheck {
public:
explicit ScopedRecursiveCheck(ThreadCollisionWarner* warner)
: warner_(warner) {
diff --git a/base/threading/thread_collision_warner_unittest.cc b/base/threading/thread_collision_warner_unittest.cc
index a3d3b66..4613955 100644
--- a/base/threading/thread_collision_warner_unittest.cc
+++ b/base/threading/thread_collision_warner_unittest.cc
@@ -1,9 +1,9 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
#include "base/compiler_specific.h"
-#include "base/scoped_ptr.h"
+#include "base/memory/scoped_ptr.h"
#include "base/synchronization/lock.h"
#include "base/threading/platform_thread.h"
#include "base/threading/simple_thread.h"
diff --git a/base/threading/thread_local.h b/base/threading/thread_local.h
index 069543f..4bacf92 100644
--- a/base/threading/thread_local.h
+++ b/base/threading/thread_local.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -49,6 +49,7 @@
#define BASE_THREADING_THREAD_LOCAL_H_
#pragma once
+#include "base/base_api.h"
#include "base/basictypes.h"
#if defined(OS_POSIX)
@@ -60,7 +61,7 @@ namespace base {
namespace internal {
// Helper functions that abstract the cross-platform APIs. Do not use directly.
-struct ThreadLocalPlatform {
+struct BASE_API ThreadLocalPlatform {
#if defined(OS_WIN)
typedef unsigned long SlotType;
#elif defined(OS_POSIX)
diff --git a/base/threading/thread_local_storage.h b/base/threading/thread_local_storage.h
index 204b653..f882729 100644
--- a/base/threading/thread_local_storage.h
+++ b/base/threading/thread_local_storage.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -6,6 +6,7 @@
#define BASE_THREADING_THREAD_LOCAL_STORAGE_H_
#pragma once
+#include "base/base_api.h"
#include "base/basictypes.h"
#if defined(OS_POSIX)
@@ -16,7 +17,7 @@ namespace base {
// Wrapper for thread local storage. This class doesn't do much except provide
// an API for portability.
-class ThreadLocalStorage {
+class BASE_API ThreadLocalStorage {
public:
// Prototype for the TLS destructor function, which can be optionally used to
@@ -25,7 +26,7 @@ class ThreadLocalStorage {
typedef void (*TLSDestructorFunc)(void* value);
// A key representing one value stored in TLS.
- class Slot {
+ class BASE_API Slot {
public:
explicit Slot(TLSDestructorFunc destructor = NULL);
diff --git a/base/threading/thread_restrictions.h b/base/threading/thread_restrictions.h
index de8174f..98e0422 100644
--- a/base/threading/thread_restrictions.h
+++ b/base/threading/thread_restrictions.h
@@ -1,10 +1,11 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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 BASE_THREADING_THREAD_RESTRICTIONS_H_
#define BASE_THREADING_THREAD_RESTRICTIONS_H_
+#include "base/base_api.h"
#include "base/basictypes.h"
namespace base {
@@ -35,11 +36,11 @@ namespace base {
// only calls other functions in Chrome and not fopen(), you should go
// add the AssertIOAllowed checks in the helper functions.
-class ThreadRestrictions {
+class BASE_API ThreadRestrictions {
public:
// Constructing a ScopedAllowIO temporarily allows IO for the current
// thread. Doing this is almost certainly always incorrect.
- class ScopedAllowIO {
+ class BASE_API ScopedAllowIO {
public:
ScopedAllowIO() { previous_value_ = SetIOAllowed(true); }
~ScopedAllowIO() { SetIOAllowed(previous_value_); }
@@ -52,7 +53,7 @@ class ThreadRestrictions {
// Constructing a ScopedAllowSingleton temporarily allows accessing for the
// current thread. Doing this is almost always incorrect.
- class ScopedAllowSingleton {
+ class BASE_API ScopedAllowSingleton {
public:
ScopedAllowSingleton() { previous_value_ = SetSingletonAllowed(true); }
~ScopedAllowSingleton() { SetSingletonAllowed(previous_value_); }
diff --git a/base/threading/watchdog.h b/base/threading/watchdog.h
index 4af45dc..fafda43 100644
--- a/base/threading/watchdog.h
+++ b/base/threading/watchdog.h
@@ -21,6 +21,7 @@
#include <string>
+#include "base/base_api.h"
#include "base/synchronization/condition_variable.h"
#include "base/synchronization/lock.h"
#include "base/threading/platform_thread.h"
@@ -28,7 +29,7 @@
namespace base {
-class Watchdog {
+class BASE_API Watchdog {
public:
// Constructor specifies how long the Watchdog will wait before alarming.
Watchdog(const TimeDelta& duration,
diff --git a/base/threading/worker_pool.h b/base/threading/worker_pool.h
index 9a02acc..12b50b4 100644
--- a/base/threading/worker_pool.h
+++ b/base/threading/worker_pool.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -6,6 +6,7 @@
#define BASE_THREADING_WORKER_POOL_H_
#pragma once
+#include "base/base_api.h"
#include "base/tracked.h"
class Task;
@@ -20,7 +21,7 @@ namespace base {
// inside the pool must be extremely careful about other objects they access
// (MessageLoops, Singletons, etc). During shutdown these object may no longer
// exist.
-class WorkerPool {
+class BASE_API WorkerPool {
public:
// This function posts |task| to run on a worker thread. |task_is_slow|
// should be used for tasks that will take a long time to execute. Returns
diff --git a/base/threading/worker_pool_posix.cc b/base/threading/worker_pool_posix.cc
index 8466403..bd6210f 100644
--- a/base/threading/worker_pool_posix.cc
+++ b/base/threading/worker_pool_posix.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -6,7 +6,7 @@
#include "base/lazy_instance.h"
#include "base/logging.h"
-#include "base/ref_counted.h"
+#include "base/memory/ref_counted.h"
#include "base/stringprintf.h"
#include "base/task.h"
#include "base/threading/platform_thread.h"
diff --git a/base/threading/worker_pool_posix.h b/base/threading/worker_pool_posix.h
index 1b68aef..701157a 100644
--- a/base/threading/worker_pool_posix.h
+++ b/base/threading/worker_pool_posix.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
//
@@ -29,8 +29,8 @@
#include <string>
#include "base/basictypes.h"
-#include "base/ref_counted.h"
-#include "base/scoped_ptr.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
#include "base/synchronization/condition_variable.h"
#include "base/synchronization/lock.h"
#include "base/threading/platform_thread.h"
diff --git a/base/time.h b/base/time.h
index ed4e772..cc99faa 100644
--- a/base/time.h
+++ b/base/time.h
@@ -25,6 +25,7 @@
#include <time.h>
+#include "base/base_api.h"
#include "base/basictypes.h"
#if defined(OS_POSIX)
@@ -48,7 +49,7 @@ class PageLoadTrackerUnitTest;
// TimeDelta ------------------------------------------------------------------
-class TimeDelta {
+class BASE_API TimeDelta {
public:
TimeDelta() : delta_(0) {
}
@@ -178,7 +179,7 @@ inline TimeDelta operator*(int64 a, TimeDelta td) {
// Time -----------------------------------------------------------------------
// Represents a wall clock time.
-class Time {
+class BASE_API Time {
public:
static const int64 kMillisecondsPerSecond = 1000;
static const int64 kMicrosecondsPerMillisecond = 1000;
@@ -204,7 +205,7 @@ class Time {
// Represents an exploded time that can be formatted nicely. This is kind of
// like the Win32 SYSTEMTIME structure or the Unix "struct tm" with a few
// additions and changes to prevent errors.
- struct Exploded {
+ struct BASE_API Exploded {
int year; // Four digit year "2007"
int month; // 1-based month (values 1 = January, etc.)
int day_of_week; // 0-based day of week (0 = Sunday, etc.)
@@ -449,7 +450,7 @@ inline Time TimeDelta::operator+(Time t) const {
// TimeTicks ------------------------------------------------------------------
-class TimeTicks {
+class BASE_API TimeTicks {
public:
TimeTicks() : ticks_(0) {
}
diff --git a/base/time_posix.cc b/base/time_posix.cc
index 62e6e49..4b29cea 100644
--- a/base/time_posix.cc
+++ b/base/time_posix.cc
@@ -109,8 +109,10 @@ Time Time::FromExploded(bool is_local, const Exploded& exploded) {
timestruct.tm_wday = exploded.day_of_week; // mktime/timegm ignore this
timestruct.tm_yday = 0; // mktime/timegm ignore this
timestruct.tm_isdst = -1; // attempt to figure it out
+#if !defined(OS_NACL)
timestruct.tm_gmtoff = 0; // not a POSIX field, so mktime/timegm ignore
timestruct.tm_zone = NULL; // not a POSIX field, so mktime/timegm ignore
+#endif
time_t seconds;
if (is_local)
@@ -179,6 +181,15 @@ TimeTicks TimeTicks::Now() {
return TimeTicks(absolute_micro);
}
+#elif defined(OS_NACL)
+
+TimeTicks TimeTicks::Now() {
+ // Sadly, Native Client does not have _POSIX_TIMERS enabled in sys/features.h
+ // Apparently NaCl only has CLOCK_REALTIME:
+ // http://code.google.com/p/nativeclient/issues/detail?id=1159
+ return TimeTicks(clock());
+}
+
#else // _POSIX_MONOTONIC_CLOCK
#error No usable tick clock function on this platform.
#endif // _POSIX_MONOTONIC_CLOCK
diff --git a/base/time_win.cc b/base/time_win.cc
index 601211c..883c486 100644
--- a/base/time_win.cc
+++ b/base/time_win.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -43,7 +43,7 @@
#include "base/basictypes.h"
#include "base/logging.h"
#include "base/cpu.h"
-#include "base/singleton.h"
+#include "base/memory/singleton.h"
#include "base/synchronization/lock.h"
using base::Time;
diff --git a/base/timer.h b/base/timer.h
index 0de7c79..6fe826a 100644
--- a/base/timer.h
+++ b/base/timer.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -47,6 +47,7 @@
// because they're flaky on the buildbot, but when you run them locally you
// should be able to tell the difference.
+#include "base/base_api.h"
#include "base/logging.h"
#include "base/task.h"
#include "base/time.h"
@@ -61,7 +62,7 @@ namespace base {
//
// This class exists to share code between BaseTimer<T> template instantiations.
//
-class BaseTimer_Helper {
+class BASE_API BaseTimer_Helper {
public:
// Stops the timer.
~BaseTimer_Helper() {
@@ -232,7 +233,7 @@ class DelayTimer {
private:
void DelayFor(TimeDelta delay) {
- trigger_time_ = Time::Now() + delay;
+ trigger_time_ = TimeTicks::Now() + delay;
// If we already have a timer that will expire at or before the given delay,
// then we have nothing more to do now.
@@ -249,7 +250,7 @@ class DelayTimer {
return;
// If we have not waited long enough, then wait some more.
- const Time now = Time::Now();
+ const TimeTicks now = TimeTicks::Now();
if (now < trigger_time_) {
DelayFor(trigger_time_ - now);
return;
@@ -263,7 +264,7 @@ class DelayTimer {
const TimeDelta delay_;
OneShotTimer<DelayTimer<Receiver> > timer_;
- Time trigger_time_;
+ TimeTicks trigger_time_;
};
} // namespace base
diff --git a/base/timer_unittest.cc b/base/timer_unittest.cc
index c2289c8..79d3a4e 100644
--- a/base/timer_unittest.cc
+++ b/base/timer_unittest.cc
@@ -1,9 +1,9 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
+#include "base/memory/scoped_ptr.h"
#include "base/message_loop.h"
-#include "base/scoped_ptr.h"
#include "base/task.h"
#include "base/timer.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/base/tracked.h b/base/tracked.h
index b4f6e36..45776d1 100644
--- a/base/tracked.h
+++ b/base/tracked.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -21,6 +21,7 @@
#include <string>
+#include "base/base_api.h"
#include "base/time.h"
#ifndef NDEBUG
@@ -35,7 +36,7 @@ namespace tracked_objects {
// Location provides basic info where of an object was constructed, or was
// significantly brought to life.
-class Location {
+class BASE_API Location {
public:
// Constructor should be called with a long-lived char*, such as __FILE__.
// It assumes the provided value will persist as a global constant, and it
@@ -87,7 +88,7 @@ class Location {
class Births;
-class Tracked {
+class BASE_API Tracked {
public:
Tracked();
virtual ~Tracked();
diff --git a/base/tracked_objects.cc b/base/tracked_objects.cc
index d10603d..b5fc146 100644
--- a/base/tracked_objects.cc
+++ b/base/tracked_objects.cc
@@ -452,7 +452,7 @@ void ThreadData::RunOnAllThreads(void (*function)()) {
int ret_val = CloseHandle(completion_handle);
DCHECK(ret_val);
}
-#endif
+#endif // OS_WIN
// static
bool ThreadData::StartTracking(bool status) {
diff --git a/base/tracked_objects.h b/base/tracked_objects.h
index ac49225..99b5ed2 100644
--- a/base/tracked_objects.h
+++ b/base/tracked_objects.h
@@ -10,6 +10,7 @@
#include <string>
#include <vector>
+#include "base/base_api.h"
#include "base/synchronization/lock.h"
#include "base/tracked.h"
#include "base/threading/thread_local_storage.h"
@@ -156,7 +157,7 @@ namespace tracked_objects {
// For a specific thread, and a specific birth place, the collection of all
// death info (with tallies for each death thread, to prevent access conflicts).
class ThreadData;
-class BirthOnThread {
+class BASE_API BirthOnThread {
public:
explicit BirthOnThread(const Location& location);
@@ -179,7 +180,7 @@ class BirthOnThread {
//------------------------------------------------------------------------------
// A class for accumulating counts of births (without bothering with a map<>).
-class Births: public BirthOnThread {
+class BASE_API Births: public BirthOnThread {
public:
explicit Births(const Location& location);
@@ -207,7 +208,7 @@ class Births: public BirthOnThread {
// birthplace (fixed Location). Used both on specific threads, and also used
// in snapshots when integrating assembled data.
-class DeathData {
+class BASE_API DeathData {
public:
// Default initializer.
DeathData() : count_(0), square_duration_(0) {}
@@ -248,7 +249,7 @@ class DeathData {
// The source of this data was collected on many threads, and is asynchronously
// changing. The data in this instance is not asynchronously changing.
-class Snapshot {
+class BASE_API Snapshot {
public:
// When snapshotting a full life cycle set (birth-to-death), use this:
Snapshot(const BirthOnThread& birth_on_thread, const ThreadData& death_thread,
@@ -284,7 +285,7 @@ class Snapshot {
// items. It protects the gathering under locks, so that it could be called via
// Posttask on any threads, or passed to all the target threads in parallel.
-class DataCollector {
+class BASE_API DataCollector {
public:
typedef std::vector<Snapshot> Collection;
@@ -331,7 +332,7 @@ class DataCollector {
// Aggregation contains summaries (totals and subtotals) of groups of Snapshot
// instances to provide printing of these collections on a single line.
-class Aggregation: public DeathData {
+class BASE_API Aggregation: public DeathData {
public:
Aggregation();
~Aggregation();
@@ -357,13 +358,13 @@ class Aggregation: public DeathData {
//------------------------------------------------------------------------------
// Comparator is a class that supports the comparison of Snapshot instances.
// An instance is actually a list of chained Comparitors, that can provide for
-// arbitrary ordering. The path portion of an about:objects URL is translated
+// arbitrary ordering. The path portion of an about:tasks URL is translated
// into such a chain, which is then used to order Snapshot instances in a
// vector. It orders them into groups (for aggregation), and can also order
// instances within the groups (for detailed rendering of the instances in an
// aggregation).
-class Comparator {
+class BASE_API Comparator {
public:
// Selector enum is the token identifier for each parsed keyword, most of
// which specify a sort order.
@@ -423,7 +424,7 @@ class Comparator {
// Translate a keyword and restriction in URL path to a selector for sorting.
void ParseKeyphrase(const std::string& key_phrase);
- // Parse a query in an about:objects URL to decide on sort ordering.
+ // Parse a query in an about:tasks URL to decide on sort ordering.
bool ParseQuery(const std::string& query);
// Output a header line that can be used to indicated what items will be
@@ -464,7 +465,7 @@ class Comparator {
// For each thread, we have a ThreadData that stores all tracking info generated
// on this thread. This prevents the need for locking as data accumulates.
-class ThreadData {
+class BASE_API ThreadData {
public:
typedef std::map<Location, Births*> BirthMap;
typedef std::map<const Births*, DeathData> DeathMap;
@@ -479,8 +480,7 @@ class ThreadData {
// return null.
static ThreadData* current();
- // For a given about:objects URL, develop resulting HTML, and append to
- // output.
+ // For a given about:tasks URL, develop resulting HTML, and append to output.
static void WriteHTML(const std::string& query, std::string* output);
// For a given accumulated array of results, use the comparator to sort and
@@ -505,7 +505,7 @@ class ThreadData {
// Using our lock, make a copy of the specified maps. These calls may arrive
// from non-local threads, and are used to quickly scan data from all threads
- // in order to build an HTML page for about:objects.
+ // in order to build an HTML page for about:tasks.
void SnapshotBirthMap(BirthMap *output) const;
void SnapshotDeathMap(DeathMap *output) const;
diff --git a/base/utf_offset_string_conversions.cc b/base/utf_offset_string_conversions.cc
index 4c47ef8..6f51ca9 100644
--- a/base/utf_offset_string_conversions.cc
+++ b/base/utf_offset_string_conversions.cc
@@ -1,9 +1,12 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
#include "base/utf_offset_string_conversions.h"
+#include <algorithm>
+
+#include "base/scoped_ptr.h"
#include "base/string_piece.h"
#include "base/utf_string_conversion_utils.h"
@@ -21,13 +24,16 @@ template<typename SRC_CHAR>
bool ConvertUnicode(const SRC_CHAR* src,
size_t src_len,
std::wstring* output,
- size_t* offset_for_adjustment) {
- size_t output_offset =
- (offset_for_adjustment && *offset_for_adjustment < src_len) ?
- *offset_for_adjustment : std::wstring::npos;
+ std::vector<size_t>* offsets_for_adjustment) {
+ if (offsets_for_adjustment) {
+ std::for_each(offsets_for_adjustment->begin(),
+ offsets_for_adjustment->end(),
+ LimitOffset<std::wstring>(src_len));
+ }
// ICU requires 32-bit numbers.
bool success = true;
+ AdjustOffset::Adjustments adjustments;
int32 src_len32 = static_cast<int32>(src_len);
for (int32 i = 0; i < src_len32; i++) {
uint32 code_point;
@@ -39,21 +45,23 @@ bool ConvertUnicode(const SRC_CHAR* src,
chars_written = WriteUnicodeCharacter(0xFFFD, output);
success = false;
}
- if ((output_offset != std::wstring::npos) &&
- (*offset_for_adjustment > original_i)) {
+ if (offsets_for_adjustment) {
// NOTE: ReadUnicodeCharacter() adjusts |i| to point _at_ the last
// character read, not after it (so that incrementing it in the loop
// increment will place it at the right location), so we need to account
// for that in determining the amount that was read.
- if (*offset_for_adjustment <= static_cast<size_t>(i))
- output_offset = std::wstring::npos;
- else
- output_offset += chars_written - (i - original_i + 1);
+ adjustments.push_back(AdjustOffset::Adjustment(
+ original_i, i - original_i + 1, chars_written));
}
}
- if (offset_for_adjustment)
- *offset_for_adjustment = output_offset;
+ // Make offset adjustment.
+ if (offsets_for_adjustment && !adjustments.empty()) {
+ std::for_each(offsets_for_adjustment->begin(),
+ offsets_for_adjustment->end(),
+ AdjustOffset(adjustments));
+ }
+
return success;
}
@@ -63,16 +71,44 @@ bool UTF8ToWideAndAdjustOffset(const char* src,
size_t src_len,
std::wstring* output,
size_t* offset_for_adjustment) {
+ std::vector<size_t> offsets;
+ if (offset_for_adjustment)
+ offsets.push_back(*offset_for_adjustment);
PrepareForUTF16Or32Output(src, src_len, output);
- return ConvertUnicode(src, src_len, output, offset_for_adjustment);
+ bool ret = ConvertUnicode(src, src_len, output, &offsets);
+ if (offset_for_adjustment)
+ *offset_for_adjustment = offsets[0];
+ return ret;
+}
+
+bool UTF8ToWideAndAdjustOffsets(const char* src,
+ size_t src_len,
+ std::wstring* output,
+ std::vector<size_t>* offsets_for_adjustment) {
+ PrepareForUTF16Or32Output(src, src_len, output);
+ return ConvertUnicode(src, src_len, output, offsets_for_adjustment);
}
std::wstring UTF8ToWideAndAdjustOffset(const base::StringPiece& utf8,
size_t* offset_for_adjustment) {
- std::wstring ret;
- UTF8ToWideAndAdjustOffset(utf8.data(), utf8.length(), &ret,
- offset_for_adjustment);
- return ret;
+ std::vector<size_t> offsets;
+ if (offset_for_adjustment)
+ offsets.push_back(*offset_for_adjustment);
+ std::wstring result;
+ UTF8ToWideAndAdjustOffsets(utf8.data(), utf8.length(), &result,
+ &offsets);
+ if (offset_for_adjustment)
+ *offset_for_adjustment = offsets[0];
+ return result;
+}
+
+std::wstring UTF8ToWideAndAdjustOffsets(const base::StringPiece& utf8,
+ std::vector<size_t>*
+ offsets_for_adjustment) {
+ std::wstring result;
+ UTF8ToWideAndAdjustOffsets(utf8.data(), utf8.length(), &result,
+ offsets_for_adjustment);
+ return result;
}
// UTF-16 <-> Wide -------------------------------------------------------------
@@ -90,6 +126,19 @@ bool UTF16ToWideAndAdjustOffset(const char16* src,
return true;
}
+bool UTF16ToWideAndAdjustOffsets(const char16* src,
+ size_t src_len,
+ std::wstring* output,
+ std::vector<size_t>* offsets_for_adjustment) {
+ output->assign(src, src_len);
+ if (offsets_for_adjustment) {
+ std::for_each(offsets_for_adjustment->begin(),
+ offsets_for_adjustment->end(),
+ LimitOffset<std::wstring>(src_len));
+ }
+ return true;
+}
+
std::wstring UTF16ToWideAndAdjustOffset(const string16& utf16,
size_t* offset_for_adjustment) {
if (offset_for_adjustment && (*offset_for_adjustment >= utf16.length()))
@@ -97,25 +146,99 @@ std::wstring UTF16ToWideAndAdjustOffset(const string16& utf16,
return utf16;
}
+std::wstring UTF16ToWideAndAdjustOffsets(
+ const string16& utf16,
+ std::vector<size_t>* offsets_for_adjustment) {
+ if (offsets_for_adjustment) {
+ std::for_each(offsets_for_adjustment->begin(),
+ offsets_for_adjustment->end(),
+ LimitOffset<std::wstring>(utf16.length()));
+ }
+ return utf16;
+}
+
#elif defined(WCHAR_T_IS_UTF32)
bool UTF16ToWideAndAdjustOffset(const char16* src,
size_t src_len,
std::wstring* output,
size_t* offset_for_adjustment) {
+ std::vector<size_t> offsets;
+ if (offset_for_adjustment)
+ offsets.push_back(*offset_for_adjustment);
output->clear();
// Assume that normally we won't have any non-BMP characters so the counts
// will be the same.
output->reserve(src_len);
- return ConvertUnicode(src, src_len, output, offset_for_adjustment);
+ bool ret = ConvertUnicode(src, src_len, output, &offsets);
+ if (offset_for_adjustment)
+ *offset_for_adjustment = offsets[0];
+ return ret;
+}
+
+bool UTF16ToWideAndAdjustOffsets(const char16* src,
+ size_t src_len,
+ std::wstring* output,
+ std::vector<size_t>* offsets_for_adjustment) {
+ output->clear();
+ // Assume that normally we won't have any non-BMP characters so the counts
+ // will be the same.
+ output->reserve(src_len);
+ return ConvertUnicode(src, src_len, output, offsets_for_adjustment);
}
std::wstring UTF16ToWideAndAdjustOffset(const string16& utf16,
size_t* offset_for_adjustment) {
- std::wstring ret;
- UTF16ToWideAndAdjustOffset(utf16.data(), utf16.length(), &ret,
- offset_for_adjustment);
- return ret;
+ std::vector<size_t> offsets;
+ if (offset_for_adjustment)
+ offsets.push_back(*offset_for_adjustment);
+ std::wstring result;
+ UTF16ToWideAndAdjustOffsets(utf16.data(), utf16.length(), &result,
+ &offsets);
+ if (offset_for_adjustment)
+ *offset_for_adjustment = offsets[0];
+ return result;
+}
+
+std::wstring UTF16ToWideAndAdjustOffsets(
+ const string16& utf16,
+ std::vector<size_t>* offsets_for_adjustment) {
+ std::wstring result;
+ UTF16ToWideAndAdjustOffsets(utf16.data(), utf16.length(), &result,
+ offsets_for_adjustment);
+ return result;
}
#endif // defined(WCHAR_T_IS_UTF32)
+
+AdjustOffset::Adjustment::Adjustment(size_t location,
+ size_t old_length,
+ size_t new_length)
+ : location(location),
+ old_length(old_length),
+ new_length(new_length) {}
+
+AdjustOffset::AdjustOffset(const Adjustments& adjustments)
+ : adjustments_(adjustments) {}
+
+void AdjustOffset::operator()(size_t& offset) {
+ if (offset == std::wstring::npos)
+ return;
+ size_t adjustment = 0;
+ for (Adjustments::const_iterator i = adjustments_.begin();
+ i != adjustments_.end(); ++i) {
+ size_t location = i->location;
+ if (offset == location && i->new_length == 0) {
+ offset = std::wstring::npos;
+ return;
+ }
+ if (offset <= location)
+ break;
+ if (offset < (location + i->old_length)) {
+ offset = std::wstring::npos;
+ return;
+ }
+ adjustment += (i->old_length - i->new_length);
+ }
+ offset -= adjustment;
+}
diff --git a/base/utf_offset_string_conversions.h b/base/utf_offset_string_conversions.h
index b20e4b1..152eda3 100644
--- a/base/utf_offset_string_conversions.h
+++ b/base/utf_offset_string_conversions.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -7,30 +7,92 @@
#pragma once
#include <string>
+#include <vector>
+#include "base/base_api.h"
#include "base/string16.h"
namespace base {
class StringPiece;
}
-// Like the conversions in utf_string_conversions.h, but also take offsets into
-// the source strings, which will be adjusted to point at the same logical place
-// in the result strings. If this isn't possible because the offsets point past
-// the end of the source strings or into the middle of multibyte sequences, they
-// will be set to std::wstring::npos. |offset_for_adjustment| may be NULL.
-bool UTF8ToWideAndAdjustOffset(const char* src,
- size_t src_len,
- std::wstring* output,
- size_t* offset_for_adjustment);
-std::wstring UTF8ToWideAndAdjustOffset(const base::StringPiece& utf8,
- size_t* offset_for_adjustment);
-
-bool UTF16ToWideAndAdjustOffset(const char16* src,
- size_t src_len,
- std::wstring* output,
- size_t* offset_for_adjustment);
-std::wstring UTF16ToWideAndAdjustOffset(const string16& utf16,
+// Like the conversions in utf_string_conversions.h, but also takes one or more
+// offsets (|offset[s]_for_adjustment|) into the source strings, each offset
+// will be adjusted to point at the same logical place in the result strings.
+// If this isn't possible because an offset points past the end of the source
+// strings or into the middle of a multibyte sequence, the offending offset will
+// be set to std::wstring::npos. |offset[s]_for_adjustment| may be NULL.
+BASE_API bool UTF8ToWideAndAdjustOffset(const char* src,
+ size_t src_len,
+ std::wstring* output,
size_t* offset_for_adjustment);
+BASE_API bool UTF8ToWideAndAdjustOffsets(
+ const char* src,
+ size_t src_len,
+ std::wstring* output,
+ std::vector<size_t>* offsets_for_adjustment);
+
+BASE_API std::wstring UTF8ToWideAndAdjustOffset(const base::StringPiece& utf8,
+ size_t* offset_for_adjustment);
+BASE_API std::wstring UTF8ToWideAndAdjustOffsets(
+ const base::StringPiece& utf8,
+ std::vector<size_t>* offsets_for_adjustment);
+
+BASE_API bool UTF16ToWideAndAdjustOffset(const char16* src,
+ size_t src_len,
+ std::wstring* output,
+ size_t* offset_for_adjustment);
+BASE_API bool UTF16ToWideAndAdjustOffsets(
+ const char16* src,
+ size_t src_len,
+ std::wstring* output,
+ std::vector<size_t>* offsets_for_adjustment);
+
+BASE_API std::wstring UTF16ToWideAndAdjustOffset(const string16& utf16,
+ size_t* offset_for_adjustment);
+BASE_API std::wstring UTF16ToWideAndAdjustOffsets(
+ const string16& utf16,
+ std::vector<size_t>* offsets_for_adjustment);
+
+// Limiting function callable by std::for_each which will replace any value
+// which is equal to or greater than |limit| with npos.
+template <typename T>
+struct LimitOffset {
+ explicit LimitOffset(size_t limit)
+ : limit_(limit) {}
+
+ void operator()(size_t& offset) {
+ if (offset >= limit_)
+ offset = T::npos;
+ }
+
+ size_t limit_;
+};
+
+// Adjustment function called by std::transform which will adjust any offset
+// that occurs after one or more modified substrings. To use, create any
+// number of AdjustOffset::Adjustments, drop them into a vector, then call
+// std::transform with the transform function being something similar to
+// AdjustOffset(adjustments). Each Adjustment gives the original |location|
+// of the encoded section and the |old_length| and |new_length| of the section
+// before and after decoding.
+struct AdjustOffset {
+ // Helper structure which indicates where an encoded character occurred
+ // and how long that encoding was.
+ struct Adjustment {
+ Adjustment(size_t location, size_t old_length, size_t new_length);
+
+ size_t location;
+ size_t old_length;
+ size_t new_length;
+ };
+
+ typedef std::vector<Adjustment> Adjustments;
+
+ explicit AdjustOffset(const Adjustments& adjustments);
+ void operator()(size_t& offset);
+
+ const Adjustments& adjustments_;
+};
#endif // BASE_UTF_OFFSET_STRING_CONVERSIONS_H_
diff --git a/base/utf_offset_string_conversions_unittest.cc b/base/utf_offset_string_conversions_unittest.cc
index 4f13ab3..b731b9e 100644
--- a/base/utf_offset_string_conversions_unittest.cc
+++ b/base/utf_offset_string_conversions_unittest.cc
@@ -1,7 +1,9 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
+#include <algorithm>
+
#include "base/logging.h"
#include "base/string_piece.h"
#include "base/utf_offset_string_conversions.h"
@@ -11,6 +13,8 @@ namespace base {
namespace {
+static const size_t kNpos = std::wstring::npos;
+
// Given a null-terminated string of wchar_t with each wchar_t representing
// a UTF-16 code unit, returns a string16 made up of wchar_t's in the input.
// Each wchar_t should be <= 0xFFFF and a non-BMP character (> U+FFFF)
@@ -40,12 +44,12 @@ TEST(UTFOffsetStringConversionsTest, AdjustOffset) {
size_t input_offset;
size_t output_offset;
} utf8_to_wide_cases[] = {
- {"", 0, std::wstring::npos},
- {"\xe4\xbd\xa0\xe5\xa5\xbd", 1, std::wstring::npos},
+ {"", 0, kNpos},
+ {"\xe4\xbd\xa0\xe5\xa5\xbd", 1, kNpos},
{"\xe4\xbd\xa0\xe5\xa5\xbd", 3, 1},
{"\xed\xb0\x80z", 3, 1},
{"A\xF0\x90\x8C\x80z", 1, 1},
- {"A\xF0\x90\x8C\x80z", 2, std::wstring::npos},
+ {"A\xF0\x90\x8C\x80z", 2, kNpos},
#if defined(WCHAR_T_IS_UTF16)
{"A\xF0\x90\x8C\x80z", 5, 3},
#elif defined(WCHAR_T_IS_UTF32)
@@ -65,7 +69,7 @@ TEST(UTFOffsetStringConversionsTest, AdjustOffset) {
size_t output_offset;
} utf16_to_wide_cases[] = {
{L"\xD840\xDC00\x4E00", 0, 0},
- {L"\xD840\xDC00\x4E00", 1, std::wstring::npos},
+ {L"\xD840\xDC00\x4E00", 1, kNpos},
{L"\xD840\xDC00\x4E00", 2, 1},
};
for (size_t i = 0; i < ARRAYSIZE_UNSAFE(utf16_to_wide_cases); ++i) {
@@ -77,4 +81,84 @@ TEST(UTFOffsetStringConversionsTest, AdjustOffset) {
#endif
}
+TEST(UTFOffsetStringConversionsTest, LimitOffsets) {
+ const size_t kLimit = 10;
+ const size_t kItems = 20;
+ std::vector<size_t> size_ts;
+ for (size_t t = 0; t < kItems; ++t)
+ size_ts.push_back(t);
+ std::for_each(size_ts.begin(), size_ts.end(),
+ LimitOffset<std::wstring>(kLimit));
+ size_t unlimited_count = 0;
+ for (std::vector<size_t>::iterator ti = size_ts.begin(); ti != size_ts.end();
+ ++ti) {
+ if (*ti < kLimit && *ti != kNpos)
+ ++unlimited_count;
+ }
+ EXPECT_EQ(10U, unlimited_count);
+
+ // Reverse the values in the vector and try again.
+ size_ts.clear();
+ for (size_t t = kItems; t > 0; --t)
+ size_ts.push_back(t - 1);
+ std::for_each(size_ts.begin(), size_ts.end(),
+ LimitOffset<std::wstring>(kLimit));
+ unlimited_count = 0;
+ for (std::vector<size_t>::iterator ti = size_ts.begin(); ti != size_ts.end();
+ ++ti) {
+ if (*ti < kLimit && *ti != kNpos)
+ ++unlimited_count;
+ }
+ EXPECT_EQ(10U, unlimited_count);
+}
+
+TEST(UTFOffsetStringConversionsTest, AdjustOffsets) {
+ // Imagine we have strings as shown in the following cases where the
+ // X's represent encoded characters.
+ // 1: abcXXXdef ==> abcXdef
+ std::vector<size_t> offsets;
+ for (size_t t = 0; t < 9; ++t)
+ offsets.push_back(t);
+ AdjustOffset::Adjustments adjustments;
+ adjustments.push_back(AdjustOffset::Adjustment(3, 3, 1));
+ std::for_each(offsets.begin(), offsets.end(), AdjustOffset(adjustments));
+ size_t expected_1[] = {0, 1, 2, 3, kNpos, kNpos, 4, 5, 6};
+ EXPECT_EQ(offsets.size(), arraysize(expected_1));
+ for (size_t i = 0; i < arraysize(expected_1); ++i)
+ EXPECT_EQ(expected_1[i], offsets[i]);
+
+ // 2: XXXaXXXXbcXXXXXXXdefXXX ==> XaXXbcXXXXdefX
+ offsets.clear();
+ for (size_t t = 0; t < 23; ++t)
+ offsets.push_back(t);
+ adjustments.clear();
+ adjustments.push_back(AdjustOffset::Adjustment(0, 3, 1));
+ adjustments.push_back(AdjustOffset::Adjustment(4, 4, 2));
+ adjustments.push_back(AdjustOffset::Adjustment(10, 7, 4));
+ adjustments.push_back(AdjustOffset::Adjustment(20, 3, 1));
+ std::for_each(offsets.begin(), offsets.end(), AdjustOffset(adjustments));
+ size_t expected_2[] = {0, kNpos, kNpos, 1, 2, kNpos, kNpos, kNpos, 4, 5, 6,
+ kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, 10, 11, 12,
+ 13, kNpos, kNpos};
+ EXPECT_EQ(offsets.size(), arraysize(expected_2));
+ for (size_t i = 0; i < arraysize(expected_2); ++i)
+ EXPECT_EQ(expected_2[i], offsets[i]);
+
+ // 3: XXXaXXXXbcdXXXeXX ==> aXXXXbcdXXXe
+ offsets.clear();
+ for (size_t t = 0; t < 17; ++t)
+ offsets.push_back(t);
+ adjustments.clear();
+ adjustments.push_back(AdjustOffset::Adjustment(0, 3, 0));
+ adjustments.push_back(AdjustOffset::Adjustment(4, 4, 4));
+ adjustments.push_back(AdjustOffset::Adjustment(11, 3, 3));
+ adjustments.push_back(AdjustOffset::Adjustment(15, 2, 0));
+ std::for_each(offsets.begin(), offsets.end(), AdjustOffset(adjustments));
+ size_t expected_3[] = {kNpos, kNpos, kNpos, 0, 1, kNpos, kNpos, kNpos, 5, 6,
+ 7, 8, kNpos, kNpos, 11, kNpos, kNpos};
+ EXPECT_EQ(offsets.size(), arraysize(expected_3));
+ for (size_t i = 0; i < arraysize(expected_3); ++i)
+ EXPECT_EQ(expected_3[i], offsets[i]);
+}
+
} // namaspace base
diff --git a/base/utf_string_conversions.h b/base/utf_string_conversions.h
index 4aa4d41..9e4af87 100644
--- a/base/utf_string_conversions.h
+++ b/base/utf_string_conversions.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -8,6 +8,7 @@
#include <string>
+#include "base/base_api.h"
#include "base/string16.h"
#include "base/string_piece.h"
@@ -17,20 +18,23 @@
// do the best it can and put the result in the output buffer. The versions that
// return strings ignore this error and just return the best conversion
// possible.
-bool WideToUTF8(const wchar_t* src, size_t src_len, std::string* output);
-std::string WideToUTF8(const std::wstring& wide);
-bool UTF8ToWide(const char* src, size_t src_len, std::wstring* output);
-std::wstring UTF8ToWide(const base::StringPiece& utf8);
-
-bool WideToUTF16(const wchar_t* src, size_t src_len, string16* output);
-string16 WideToUTF16(const std::wstring& wide);
-bool UTF16ToWide(const char16* src, size_t src_len, std::wstring* output);
-std::wstring UTF16ToWide(const string16& utf16);
-
-bool UTF8ToUTF16(const char* src, size_t src_len, string16* output);
-string16 UTF8ToUTF16(const base::StringPiece& utf8);
-bool UTF16ToUTF8(const char16* src, size_t src_len, std::string* output);
-std::string UTF16ToUTF8(const string16& utf16);
+BASE_API bool WideToUTF8(const wchar_t* src, size_t src_len,
+ std::string* output);
+BASE_API std::string WideToUTF8(const std::wstring& wide);
+BASE_API bool UTF8ToWide(const char* src, size_t src_len, std::wstring* output);
+BASE_API std::wstring UTF8ToWide(const base::StringPiece& utf8);
+
+BASE_API bool WideToUTF16(const wchar_t* src, size_t src_len, string16* output);
+BASE_API string16 WideToUTF16(const std::wstring& wide);
+BASE_API bool UTF16ToWide(const char16* src, size_t src_len,
+ std::wstring* output);
+BASE_API std::wstring UTF16ToWide(const string16& utf16);
+
+BASE_API bool UTF8ToUTF16(const char* src, size_t src_len, string16* output);
+BASE_API string16 UTF8ToUTF16(const base::StringPiece& utf8);
+BASE_API bool UTF16ToUTF8(const char16* src, size_t src_len,
+ std::string* output);
+BASE_API std::string UTF16ToUTF8(const string16& utf16);
// We are trying to get rid of wstring as much as possible, but it's too big
// a mess to do it all at once. These conversions should be used when we
@@ -47,7 +51,7 @@ std::string UTF16ToUTF8(const string16& utf16);
// These convert an ASCII string, typically a hardcoded constant, to a
// UTF16/Wide string.
-std::wstring ASCIIToWide(const base::StringPiece& ascii);
-string16 ASCIIToUTF16(const base::StringPiece& ascii);
+BASE_API std::wstring ASCIIToWide(const base::StringPiece& ascii);
+BASE_API string16 ASCIIToUTF16(const base::StringPiece& ascii);
#endif // BASE_UTF_STRING_CONVERSIONS_H_
diff --git a/base/value_conversions.cc b/base/value_conversions.cc
new file mode 100644
index 0000000..64513d0
--- /dev/null
+++ b/base/value_conversions.cc
@@ -0,0 +1,52 @@
+// Copyright (c) 2011 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.
+
+#include "base/value_conversions.h"
+
+#include "base/file_path.h"
+#include "base/sys_string_conversions.h"
+#include "base/utf_string_conversions.h"
+#include "base/values.h"
+
+namespace base {
+
+namespace {
+
+// |Value| internally stores strings in UTF-8, so we have to convert from the
+// system native code to UTF-8 and back.
+
+std::string FilePathToUTF8(const FilePath& file_path) {
+#if defined(OS_POSIX)
+ return WideToUTF8(SysNativeMBToWide(file_path.value()));
+#else
+ return UTF16ToUTF8(file_path.value());
+#endif
+}
+
+FilePath UTF8ToFilePath(const std::string& str) {
+ FilePath::StringType result;
+#if defined(OS_POSIX)
+ result = SysWideToNativeMB(UTF8ToWide(str));
+#elif defined(OS_WIN)
+ result = UTF8ToUTF16(str);
+#endif
+ return FilePath(result);
+}
+
+} // namespace
+
+StringValue* CreateFilePathValue(const FilePath& in_value) {
+ return new StringValue(FilePathToUTF8(in_value));
+}
+
+bool GetValueAsFilePath(const Value& value, FilePath* file_path) {
+ std::string str;
+ if (!value.GetAsString(&str))
+ return false;
+ if (file_path)
+ *file_path = UTF8ToFilePath(str);
+ return true;
+}
+
+} // namespace base
diff --git a/base/value_conversions.h b/base/value_conversions.h
new file mode 100644
index 0000000..75246d1
--- /dev/null
+++ b/base/value_conversions.h
@@ -0,0 +1,25 @@
+// Copyright (c) 2011 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 BASE_VALUE_CONVERSIONS_H_
+#define BASE_VALUE_CONVERSIONS_H_
+#pragma once
+
+// This file contains methods to convert a |FilePath| to a |Value| and back.
+
+#include "base/base_api.h"
+
+class FilePath;
+class StringValue;
+class Value;
+
+namespace base {
+
+// The caller takes ownership of the returned value.
+BASE_API StringValue* CreateFilePathValue(const FilePath& in_value);
+BASE_API bool GetValueAsFilePath(const Value& value, FilePath* file_path);
+
+} // namespace
+
+#endif // BASE_VALUE_CONVERSIONS_H_
diff --git a/base/values.cc b/base/values.cc
index 3340f9b..9f2816a 100644
--- a/base/values.cc
+++ b/base/values.cc
@@ -1,13 +1,11 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
#include "base/values.h"
-#include "base/file_path.h"
#include "base/logging.h"
#include "base/string_util.h"
-#include "base/sys_string_conversions.h"
#include "base/utf_string_conversions.h"
namespace {
@@ -97,19 +95,6 @@ StringValue* Value::CreateStringValue(const string16& in_value) {
}
// static
-StringValue* Value::CreateFilePathValue(const FilePath& in_value) {
-#if defined(OS_POSIX)
- // Value::SetString only knows about UTF8 strings, so convert the path from
- // the system native value to UTF8.
- std::string path_utf8 = WideToUTF8(base::SysNativeMBToWide(in_value.value()));
- return new StringValue(path_utf8);
-#else
- return new StringValue(in_value.value());
-#endif
-
-}
-
-// static
BinaryValue* Value::CreateBinaryValue(char* buffer, size_t size) {
return BinaryValue::Create(buffer, size);
}
@@ -134,10 +119,6 @@ bool Value::GetAsString(string16* out_value) const {
return false;
}
-bool Value::GetAsFilePath(FilePath* out_value) const {
- return false;
-}
-
bool Value::GetAsList(ListValue** out_value) {
return false;
}
@@ -269,20 +250,6 @@ bool StringValue::GetAsString(string16* out_value) const {
return true;
}
-bool StringValue::GetAsFilePath(FilePath* out_value) const {
- if (out_value) {
- FilePath::StringType result;
-#if defined(OS_POSIX)
- // We store filepaths as UTF8, so convert it back to the system type.
- result = base::SysWideToNativeMB(UTF8ToWide(value_));
-#elif defined(OS_WIN)
- result = UTF8ToUTF16(value_);
-#endif
- *out_value = FilePath(result);
- }
- return true;
-}
-
StringValue* StringValue::DeepCopy() const {
return CreateStringValue(value_);
}
@@ -873,8 +840,10 @@ void ListValue::Append(Value* in_value) {
bool ListValue::AppendIfNotPresent(Value* in_value) {
DCHECK(in_value);
for (ValueVector::const_iterator i(list_.begin()); i != list_.end(); ++i) {
- if ((*i)->Equals(in_value))
+ if ((*i)->Equals(in_value)) {
+ delete in_value;
return false;
+ }
}
list_.push_back(in_value);
return true;
diff --git a/base/values.h b/base/values.h
index 5814a9f..e4949b1 100644
--- a/base/values.h
+++ b/base/values.h
@@ -27,13 +27,13 @@
#include <string>
#include <vector>
+#include "base/base_api.h"
#include "base/basictypes.h"
#include "base/string16.h"
#include "build/build_config.h"
class BinaryValue;
class DictionaryValue;
-class FilePath;
class FundamentalValue;
class ListValue;
class StringValue;
@@ -45,7 +45,7 @@ typedef std::map<std::string, Value*> ValueMap;
// The Value class is the base class for Values. A Value can be
// instantiated via the Create*Value() factory methods, or by directly
// creating instances of the subclasses.
-class Value {
+class BASE_API Value {
public:
enum ValueType {
TYPE_NULL = 0,
@@ -69,7 +69,6 @@ class Value {
static FundamentalValue* CreateDoubleValue(double in_value);
static StringValue* CreateStringValue(const std::string& in_value);
static StringValue* CreateStringValue(const string16& in_value);
- static StringValue* CreateFilePathValue(const FilePath& in_value);
// This one can return NULL if the input isn't valid. If the return value
// is non-null, the new object has taken ownership of the buffer pointer.
@@ -94,7 +93,6 @@ class Value {
virtual bool GetAsDouble(double* out_value) const;
virtual bool GetAsString(std::string* out_value) const;
virtual bool GetAsString(string16* out_value) const;
- virtual bool GetAsFilePath(FilePath* out_value) const;
virtual bool GetAsList(ListValue** out_value);
// This creates a deep copy of the entire Value tree, and returns a pointer
@@ -125,7 +123,7 @@ class Value {
};
// FundamentalValue represents the simple fundamental types of values.
-class FundamentalValue : public Value {
+class BASE_API FundamentalValue : public Value {
public:
explicit FundamentalValue(bool in_value);
explicit FundamentalValue(int in_value);
@@ -149,7 +147,7 @@ class FundamentalValue : public Value {
DISALLOW_COPY_AND_ASSIGN(FundamentalValue);
};
-class StringValue : public Value {
+class BASE_API StringValue : public Value {
public:
// Initializes a StringValue with a UTF-8 narrow character string.
explicit StringValue(const std::string& in_value);
@@ -162,7 +160,6 @@ class StringValue : public Value {
// Subclassed methods
virtual bool GetAsString(std::string* out_value) const;
virtual bool GetAsString(string16* out_value) const;
- virtual bool GetAsFilePath(FilePath* out_value) const;
virtual StringValue* DeepCopy() const;
virtual bool Equals(const Value* other) const;
@@ -172,7 +169,7 @@ class StringValue : public Value {
DISALLOW_COPY_AND_ASSIGN(StringValue);
};
-class BinaryValue: public Value {
+class BASE_API BinaryValue: public Value {
public:
virtual ~BinaryValue();
@@ -209,7 +206,7 @@ class BinaryValue: public Value {
// DictionaryValue provides a key-value dictionary with (optional) "path"
// parsing for recursive access; see the comment at the top of the file. Keys
// are |std::string|s and should be UTF-8 encoded.
-class DictionaryValue : public Value {
+class BASE_API DictionaryValue : public Value {
public:
DictionaryValue();
virtual ~DictionaryValue();
@@ -317,7 +314,7 @@ class DictionaryValue : public Value {
// YOU SHOULD ALWAYS USE THE XXXWithoutPathExpansion() APIs WITH THESE, NOT
// THE NORMAL XXX() APIs. This makes sure things will work correctly if any
// keys have '.'s in them.
- class key_iterator
+ class BASE_API key_iterator
: private std::iterator<std::input_iterator_tag, const std::string> {
public:
explicit key_iterator(ValueMap::const_iterator itr) { itr_ = itr; }
@@ -347,7 +344,7 @@ class DictionaryValue : public Value {
};
// This type of Value represents a list of other Value values.
-class ListValue : public Value {
+class BASE_API ListValue : public Value {
public:
typedef ValueVector::iterator iterator;
typedef ValueVector::const_iterator const_iterator;
@@ -402,8 +399,9 @@ class ListValue : public Value {
// Appends a Value to the end of the list.
void Append(Value* in_value);
- // Appends a Value if it's not already present.
- // Returns true if successful, or false if the value was already present.
+ // Appends a Value if it's not already present. Takes ownership of the
+ // |in_value|. Returns true if successful, or false if the value was already
+ // present. If the value was already present the |in_value| is deleted.
bool AppendIfNotPresent(Value* in_value);
// Insert a Value at index.
@@ -435,7 +433,7 @@ class ListValue : public Value {
// This interface is implemented by classes that know how to serialize and
// deserialize Value objects.
-class ValueSerializer {
+class BASE_API ValueSerializer {
public:
virtual ~ValueSerializer();
diff --git a/base/values_unittest.cc b/base/values_unittest.cc
index 5f901b5..809fe90 100644
--- a/base/values_unittest.cc
+++ b/base/values_unittest.cc
@@ -1,10 +1,10 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
#include <limits>
-#include "base/scoped_ptr.h"
+#include "base/memory/scoped_ptr.h"
#include "base/string16.h"
#include "base/utf_string_conversions.h"
#include "base/values.h"
diff --git a/base/version.h b/base/version.h
index 28ee227..d256d06 100644
--- a/base/version.h
+++ b/base/version.h
@@ -9,13 +9,14 @@
#include <string>
#include <vector>
+#include "base/base_api.h"
#include "base/basictypes.h"
#include "base/gtest_prod_util.h"
// Version represents a dotted version number, like "1.2.3.4", supporting
// parsing and comparison.
// Each component is limited to a uint16.
-class Version {
+class BASE_API Version {
public:
// Exposed only so that a Version can be stored in STL containers;
// any call to the methods below on a default-constructed Version
diff --git a/base/version_unittest.cc b/base/version_unittest.cc
index 2e3c2ca..486ef7d 100644
--- a/base/version_unittest.cc
+++ b/base/version_unittest.cc
@@ -1,8 +1,8 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
-#include "base/scoped_ptr.h"
+#include "base/memory/scoped_ptr.h"
#include "base/version.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/base/vlog.h b/base/vlog.h
index 54e777f..0a55006 100644
--- a/base/vlog.h
+++ b/base/vlog.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -10,13 +10,14 @@
#include <string>
#include <vector>
+#include "base/base_api.h"
#include "base/basictypes.h"
#include "base/string_piece.h"
namespace logging {
// A helper class containing all the settings for vlogging.
-class VlogInfo {
+class BASE_API VlogInfo {
public:
static const int kDefaultVlogLevel;
@@ -70,8 +71,8 @@ class VlogInfo {
// "kh*n" matches "khn", "khan", or even "khaaaaan"
// "/foo\bar" matches "/foo/bar", "\foo\bar", or "/foo\bar"
// (disregarding C escaping rules)
-bool MatchVlogPattern(const base::StringPiece& string,
- const base::StringPiece& vlog_pattern);
+BASE_API bool MatchVlogPattern(const base::StringPiece& string,
+ const base::StringPiece& vlog_pattern);
} // namespace logging
diff --git a/base/win/event_trace_controller.h b/base/win/event_trace_controller.h
index 8eb172e..6cc7e69 100644
--- a/base/win/event_trace_controller.h
+++ b/base/win/event_trace_controller.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
//
@@ -25,6 +25,8 @@
#include <wmistr.h>
#include <evntrace.h>
#include <string>
+
+#include "base/base_api.h"
#include "base/basictypes.h"
namespace base {
@@ -33,7 +35,7 @@ namespace win {
// Utility class to make it easier to work with EVENT_TRACE_PROPERTIES.
// The EVENT_TRACE_PROPERTIES structure contains information about an
// event tracing session.
-class EtwTraceProperties {
+class BASE_API EtwTraceProperties {
public:
EtwTraceProperties();
@@ -83,7 +85,7 @@ class EtwTraceProperties {
// This class implements an ETW controller, which knows how to start and
// stop event tracing sessions, as well as controlling ETW provider
// log levels and enable bit masks under the session.
-class EtwTraceController {
+class BASE_API EtwTraceController {
public:
EtwTraceController();
~EtwTraceController();
diff --git a/base/win/event_trace_provider.h b/base/win/event_trace_provider.h
index 6614c91..7173025 100644
--- a/base/win/event_trace_provider.h
+++ b/base/win/event_trace_provider.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
//
@@ -11,6 +11,8 @@
#include <windows.h>
#include <wmistr.h>
#include <evntrace.h>
+
+#include "base/base_api.h"
#include "base/basictypes.h"
namespace base {
@@ -80,7 +82,7 @@ template <size_t N> class EtwMofEvent: public EtwMofEventBase<N> {
// a particular trace level, and whether particular enable flags are set,
// before other resources are consumed to generate and issue the log
// messages themselves.
-class EtwTraceProvider {
+class BASE_API EtwTraceProvider {
public:
// Creates an event trace provider identified by provider_name, which
// will be the name registered with Event Tracing for Windows (ETW).
diff --git a/base/win/i18n.h b/base/win/i18n.h
index ba0f74d..0159fd0 100644
--- a/base/win/i18n.h
+++ b/base/win/i18n.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -9,6 +9,7 @@
#include <string>
#include <vector>
+#include "base/base_api.h"
#include "base/basictypes.h"
namespace base {
@@ -18,12 +19,14 @@ namespace i18n {
// Adds to |languages| the list of user preferred UI languages from MUI, if
// available, falling-back on the user default UI language otherwise. Returns
// true if at least one language is added.
-bool GetUserPreferredUILanguageList(std::vector<std::wstring>* languages);
+BASE_API bool GetUserPreferredUILanguageList(
+ std::vector<std::wstring>* languages);
// Adds to |languages| the list of thread, process, user, and system preferred
// UI languages from MUI, if available, falling-back on the user default UI
// language otherwise. Returns true if at least one language is added.
-bool GetThreadPreferredUILanguageList(std::vector<std::wstring>* languages);
+BASE_API bool GetThreadPreferredUILanguageList(
+ std::vector<std::wstring>* languages);
} // namespace i18n
} // namespace win
diff --git a/base/win/object_watcher.h b/base/win/object_watcher.h
index 16534c2..0eef022 100644
--- a/base/win/object_watcher.h
+++ b/base/win/object_watcher.h
@@ -8,6 +8,7 @@
#include <windows.h>
+#include "base/base_api.h"
#include "base/message_loop.h"
namespace base {
@@ -41,7 +42,7 @@ namespace win {
// scope, the watcher_ will be destroyed, and there is no need to worry about
// OnObjectSignaled being called on a deleted MyClass pointer. Easy!
//
-class ObjectWatcher : public MessageLoop::DestructionObserver {
+class BASE_API ObjectWatcher : public MessageLoop::DestructionObserver {
public:
class Delegate {
public:
diff --git a/base/win/registry.h b/base/win/registry.h
index cd5421d..86785cf 100644
--- a/base/win/registry.h
+++ b/base/win/registry.h
@@ -9,6 +9,7 @@
#include <windows.h>
#include <string>
+#include "base/base_api.h"
#include "base/basictypes.h"
namespace base {
@@ -21,7 +22,7 @@ namespace win {
// Note:
// ReadValue family of functions guarantee that the return arguments
// are not touched in case of failure.
-class RegKey {
+class BASE_API RegKey {
public:
RegKey();
RegKey(HKEY rootkey, const wchar_t* subkey, REGSAM access);
@@ -98,7 +99,7 @@ class RegKey {
// For this application I happen to know I wont need data size larger
// than MAX_PATH, but in real life this wouldn't neccessarily be
// adequate.
-class RegistryValueIterator {
+class BASE_API RegistryValueIterator {
public:
RegistryValueIterator(HKEY root_key, const wchar_t* folder_key);
@@ -138,7 +139,7 @@ class RegistryValueIterator {
DISALLOW_COPY_AND_ASSIGN(RegistryValueIterator);
};
-class RegistryKeyIterator {
+class BASE_API RegistryKeyIterator {
public:
RegistryKeyIterator(HKEY root_key, const wchar_t* folder_key);
diff --git a/base/win/scoped_bstr.h b/base/win/scoped_bstr.h
index 944562e..61b8969 100644
--- a/base/win/scoped_bstr.h
+++ b/base/win/scoped_bstr.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -9,6 +9,7 @@
#include <windows.h>
#include <oleauto.h>
+#include "base/base_api.h"
#include "base/logging.h"
#include "base/string16.h"
@@ -17,7 +18,7 @@ namespace win {
// Manages a BSTR string pointer.
// The class interface is based on scoped_ptr.
-class ScopedBstr {
+class BASE_API ScopedBstr {
public:
ScopedBstr() : bstr_(NULL) {
}
diff --git a/base/win/scoped_comptr.h b/base/win/scoped_comptr.h
index e508ef2..9a4dd9d 100644
--- a/base/win/scoped_comptr.h
+++ b/base/win/scoped_comptr.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -9,7 +9,7 @@
#include <unknwn.h>
#include "base/logging.h"
-#include "base/ref_counted.h"
+#include "base/memory/ref_counted.h"
namespace base {
namespace win {
diff --git a/base/win/scoped_comptr_unittest.cc b/base/win/scoped_comptr_unittest.cc
index fcd0791..54dcfc0 100644
--- a/base/win/scoped_comptr_unittest.cc
+++ b/base/win/scoped_comptr_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -6,7 +6,7 @@
#include <shlobj.h>
-#include "base/scoped_ptr.h"
+#include "base/memory/scoped_ptr.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace base {
@@ -110,4 +110,4 @@ TEST(ScopedComPtrTest, ScopedComPtrVector) {
}
} // namespace win
-} // namespace base \ No newline at end of file
+} // namespace base
diff --git a/base/win/scoped_variant.h b/base/win/scoped_variant.h
index 6c4d23f..11ffa3e 100644
--- a/base/win/scoped_variant.h
+++ b/base/win/scoped_variant.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -9,6 +9,7 @@
#include <windows.h>
#include <oleauto.h>
+#include "base/base_api.h"
#include "base/basictypes.h"
namespace base {
@@ -20,7 +21,7 @@ namespace win {
// Instead of inheriting from VARIANT, we take the containment approach
// in order to have more control over the usage of the variant and guard
// against memory leaks.
-class ScopedVariant {
+class BASE_API ScopedVariant {
public:
// Declaration of a global variant variable that's always VT_EMPTY
static const VARIANT kEmptyVariant;
diff --git a/base/win/win_util.cc b/base/win/win_util.cc
index 76d8c5d..8a9d622 100644
--- a/base/win/win_util.cc
+++ b/base/win/win_util.cc
@@ -12,8 +12,8 @@
#include <shlobj.h>
#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
#include "base/win/registry.h"
-#include "base/scoped_ptr.h"
#include "base/string_util.h"
#include "base/stringprintf.h"
#include "base/threading/thread_restrictions.h"
diff --git a/base/win/win_util.h b/base/win/win_util.h
index c9bdce8..847c434 100644
--- a/base/win/win_util.h
+++ b/base/win/win_util.h
@@ -27,6 +27,7 @@
#include <string>
+#include "base/base_api.h"
#include "base/string16.h"
struct IPropertyStore;
@@ -36,19 +37,19 @@ typedef _tagpropertykey PROPERTYKEY;
namespace base {
namespace win {
-void GetNonClientMetrics(NONCLIENTMETRICS* metrics);
+BASE_API void GetNonClientMetrics(NONCLIENTMETRICS* metrics);
// Returns the string representing the current user sid.
-bool GetUserSidString(std::wstring* user_sid);
+BASE_API bool GetUserSidString(std::wstring* user_sid);
// Returns true if the shift key is currently pressed.
-bool IsShiftPressed();
+BASE_API bool IsShiftPressed();
// Returns true if the ctrl key is currently pressed.
-bool IsCtrlPressed();
+BASE_API bool IsCtrlPressed();
// Returns true if the alt key is currently pressed.
-bool IsAltPressed();
+BASE_API bool IsAltPressed();
// Returns false if user account control (UAC) has been disabled with the
// EnableLUA registry flag. Returns true if user account control is enabled.
@@ -56,27 +57,27 @@ bool IsAltPressed();
// machines, might still exist and be set to 0 (UAC disabled), in which case
// this function will return false. You should therefore check this flag only
// if the OS is Vista or later.
-bool UserAccountControlIsEnabled();
+BASE_API bool UserAccountControlIsEnabled();
// Sets the application id in given IPropertyStore. The function is intended
// for tagging application/chromium shortcut, browser window and jump list for
// Win7.
-bool SetAppIdForPropertyStore(IPropertyStore* property_store,
- const wchar_t* app_id);
+BASE_API bool SetAppIdForPropertyStore(IPropertyStore* property_store,
+ const wchar_t* app_id);
// Adds the specified |command| using the specified |name| to the AutoRun key.
// |root_key| could be HKCU or HKLM or the root of any user hive.
-bool AddCommandToAutoRun(HKEY root_key, const string16& name,
- const string16& command);
+BASE_API bool AddCommandToAutoRun(HKEY root_key, const string16& name,
+ const string16& command);
// Removes the command specified by |name| from the AutoRun key. |root_key|
// could be HKCU or HKLM or the root of any user hive.
-bool RemoveCommandFromAutoRun(HKEY root_key, const string16& name);
+BASE_API bool RemoveCommandFromAutoRun(HKEY root_key, const string16& name);
// Reads the command specified by |name| from the AutoRun key. |root_key|
// could be HKCU or HKLM or the root of any user hive. Used for unit-tests.
-bool ReadCommandFromAutoRun(HKEY root_key,
- const string16& name,
- string16* command);
+BASE_API bool ReadCommandFromAutoRun(HKEY root_key,
+ const string16& name,
+ string16* command);
} // namespace win
} // namespace base
diff --git a/base/win/windows_version.cc b/base/win/windows_version.cc
index d53148d..8dc2d93 100644
--- a/base/win/windows_version.cc
+++ b/base/win/windows_version.cc
@@ -11,81 +11,49 @@
namespace base {
namespace win {
-Version GetVersion() {
- static bool checked_version = false;
- static Version win_version = VERSION_PRE_2000;
- if (!checked_version) {
- OSVERSIONINFOEX version_info;
- version_info.dwOSVersionInfoSize = sizeof version_info;
- GetVersionEx(reinterpret_cast<OSVERSIONINFO*>(&version_info));
- if (version_info.dwMajorVersion == 5) {
- switch (version_info.dwMinorVersion) {
- case 0:
- win_version = VERSION_2000;
- break;
- case 1:
- win_version = VERSION_XP;
- break;
- case 2:
- default:
- win_version = VERSION_SERVER_2003;
- break;
- }
- } else if (version_info.dwMajorVersion == 6) {
- if (version_info.wProductType != VER_NT_WORKSTATION) {
- // 2008 is 6.0, and 2008 R2 is 6.1.
- win_version = VERSION_2008;
- } else {
- if (version_info.dwMinorVersion == 0) {
- win_version = VERSION_VISTA;
- } else {
- win_version = VERSION_WIN7;
- }
- }
- } else if (version_info.dwMajorVersion > 6) {
- win_version = VERSION_WIN7;
- }
- checked_version = true;
- }
- return win_version;
+// static
+OSInfo* OSInfo::GetInstance() {
+ return Singleton<OSInfo>::get();
}
-void GetServicePackLevel(int* major, int* minor) {
- DCHECK(major && minor);
- static bool checked_version = false;
- static int service_pack_major = -1;
- static int service_pack_minor = -1;
- if (!checked_version) {
- OSVERSIONINFOEX version_info = {0};
- version_info.dwOSVersionInfoSize = sizeof(version_info);
- GetVersionEx(reinterpret_cast<OSVERSIONINFOW*>(&version_info));
- service_pack_major = version_info.wServicePackMajor;
- service_pack_minor = version_info.wServicePackMinor;
- checked_version = true;
+OSInfo::OSInfo()
+ : version_(VERSION_PRE_XP),
+ architecture_(OTHER_ARCHITECTURE),
+ wow64_status_(GetWOW64StatusForProcess(GetCurrentProcess())) {
+ OSVERSIONINFOEX version_info = { sizeof version_info };
+ GetVersionEx(reinterpret_cast<OSVERSIONINFO*>(&version_info));
+ version_number_.major = version_info.dwMajorVersion;
+ version_number_.minor = version_info.dwMinorVersion;
+ version_number_.build = version_info.dwBuildNumber;
+ if ((version_number_.major == 5) && (version_number_.minor > 0)) {
+ version_ = (version_number_.minor == 1) ? VERSION_XP : VERSION_SERVER_2003;
+ } else if (version_number_.major == 6) {
+ if (version_info.wProductType == VER_NT_WORKSTATION)
+ version_ = (version_number_.minor == 0) ? VERSION_VISTA : VERSION_WIN7;
+ else
+ version_ = VERSION_SERVER_2008;
+ } else if (version_number_.major > 6) {
+ version_ = VERSION_WIN7;
}
+ service_pack_.major = version_info.wServicePackMajor;
+ service_pack_.minor = version_info.wServicePackMinor;
- *major = service_pack_major;
- *minor = service_pack_minor;
-}
-
-WindowsArchitecture GetWindowsArchitecture() {
- SYSTEM_INFO system_info;
+ SYSTEM_INFO system_info = { 0 };
GetNativeSystemInfo(&system_info);
switch (system_info.wProcessorArchitecture) {
- case PROCESSOR_ARCHITECTURE_INTEL: return X86_ARCHITECTURE;
- case PROCESSOR_ARCHITECTURE_AMD64: return X64_ARCHITECTURE;
- case PROCESSOR_ARCHITECTURE_IA64: return IA64_ARCHITECTURE;
- default: return OTHER_ARCHITECTURE;
+ case PROCESSOR_ARCHITECTURE_INTEL: architecture_ = X86_ARCHITECTURE; break;
+ case PROCESSOR_ARCHITECTURE_AMD64: architecture_ = X64_ARCHITECTURE; break;
+ case PROCESSOR_ARCHITECTURE_IA64: architecture_ = IA64_ARCHITECTURE; break;
}
+ processors_ = system_info.dwNumberOfProcessors;
+ allocation_granularity_ = system_info.dwAllocationGranularity;
}
-WOW64Status GetWOW64Status() {
- static WOW64Status wow64_status =
- GetWOW64StatusForProcess(GetCurrentProcess());
- return wow64_status;
+OSInfo::~OSInfo() {
}
-WOW64Status GetWOW64StatusForProcess(HANDLE process_handle) {
+// static
+OSInfo::WOW64Status OSInfo::GetWOW64StatusForProcess(HANDLE process_handle) {
typedef BOOL (WINAPI* IsWow64ProcessFunc)(HANDLE, PBOOL);
IsWow64ProcessFunc is_wow64_process = reinterpret_cast<IsWow64ProcessFunc>(
GetProcAddress(GetModuleHandle(L"kernel32.dll"), "IsWow64Process"));
@@ -97,5 +65,9 @@ WOW64Status GetWOW64StatusForProcess(HANDLE process_handle) {
return is_wow64 ? WOW64_ENABLED : WOW64_DISABLED;
}
+Version GetVersion() {
+ return OSInfo::GetInstance()->version();
+}
+
} // namespace win
} // namespace base
diff --git a/base/win/windows_version.h b/base/win/windows_version.h
index df3cc35..96f3792 100644
--- a/base/win/windows_version.h
+++ b/base/win/windows_version.h
@@ -6,60 +6,99 @@
#define BASE_WIN_WINDOWS_VERSION_H_
#pragma once
+#include "base/base_api.h"
+#include "base/memory/singleton.h"
+
typedef void* HANDLE;
namespace base {
namespace win {
+// The running version of Windows. This is declared outside OSInfo for
+// syntactic sugar reasons; see the declaration of GetVersion() below.
// NOTE: Keep these in order so callers can do things like
-// "if (GetWinVersion() > WINVERSION_2000) ...". It's OK to change the values,
-// though.
+// "if (base::win::GetVersion() >= base::win::VERSION_VISTA) ...".
enum Version {
- VERSION_PRE_2000 = 0, // Not supported
- VERSION_2000 = 1, // Not supported
- VERSION_XP = 2,
- VERSION_SERVER_2003 = 3, // Also includes Windows XP Professional x64 edition
- VERSION_VISTA = 4,
- VERSION_2008 = 5,
- VERSION_WIN7 = 6,
+ VERSION_PRE_XP = 0, // Not supported.
+ VERSION_XP,
+ VERSION_SERVER_2003, // Also includes Windows XP Professional x64.
+ VERSION_VISTA,
+ VERSION_SERVER_2008,
+ VERSION_WIN7,
};
-// Returns the running version of Windows.
-Version GetVersion();
+// A Singleton that can be used to query various pieces of information about the
+// OS and process state.
+class BASE_API OSInfo {
+ public:
+ struct VersionNumber {
+ int major;
+ int minor;
+ int build;
+ };
-// Returns the major and minor version of the service pack installed.
-void GetServicePackLevel(int* major, int* minor);
+ struct ServicePack {
+ int major;
+ int minor;
+ };
-enum WindowsArchitecture {
- X86_ARCHITECTURE,
- X64_ARCHITECTURE,
- IA64_ARCHITECTURE,
- OTHER_ARCHITECTURE,
-};
+ // The processor architecture this copy of Windows natively uses. For
+ // example, given an x64-capable processor, we have three possibilities:
+ // 32-bit Chrome running on 32-bit Windows: X86_ARCHITECTURE
+ // 32-bit Chrome running on 64-bit Windows via WOW64: X64_ARCHITECTURE
+ // 64-bit Chrome running on 64-bit Windows: X64_ARCHITECTURE
+ enum WindowsArchitecture {
+ X86_ARCHITECTURE,
+ X64_ARCHITECTURE,
+ IA64_ARCHITECTURE,
+ OTHER_ARCHITECTURE,
+ };
-// Returns the processor architecture this copy of Windows natively uses.
-// For example, given an x64-capable processor, we have three possibilities:
-// 32-bit Chrome running on 32-bit Windows: X86_ARCHITECTURE
-// 32-bit Chrome running on 64-bit Windows via WOW64: X64_ARCHITECTURE
-// 64-bit Chrome running on 64-bit Windows: X64_ARCHITECTURE
-WindowsArchitecture GetWindowsArchitecture();
-
-enum WOW64Status {
- WOW64_DISABLED,
- WOW64_ENABLED,
- WOW64_UNKNOWN,
-};
+ // Whether a process is running under WOW64 (the wrapper that allows 32-bit
+ // processes to run on 64-bit versions of Windows). This will return
+ // WOW64_DISABLED for both "32-bit Chrome on 32-bit Windows" and "64-bit
+ // Chrome on 64-bit Windows". WOW64_UNKNOWN means "an error occurred", e.g.
+ // the process does not have sufficient access rights to determine this.
+ enum WOW64Status {
+ WOW64_DISABLED,
+ WOW64_ENABLED,
+ WOW64_UNKNOWN,
+ };
+
+ static OSInfo* GetInstance();
+
+ Version version() const { return version_; }
+ // The next two functions return arrays of values, [major, minor(, build)].
+ VersionNumber version_number() const { return version_number_; }
+ ServicePack service_pack() const { return service_pack_; }
+ WindowsArchitecture architecture() const { return architecture_; }
+ int processors() const { return processors_; }
+ size_t allocation_granularity() const { return allocation_granularity_; }
+ WOW64Status wow64_status() const { return wow64_status_; }
-// Returns whether this process is running under WOW64 (the wrapper that allows
-// 32-bit processes to run on 64-bit versions of Windows). This will return
-// WOW64_DISABLED for both "32-bit Chrome on 32-bit Windows" and "64-bit Chrome
-// on 64-bit Windows". WOW64_UNKNOWN means "an error occurred", e.g. the
-// process does not have sufficient access rights to determine this.
-WOW64Status GetWOW64Status();
+ // Like wow64_status(), but for the supplied handle instead of the current
+ // process. This doesn't touch member state, so you can bypass the singleton.
+ static WOW64Status GetWOW64StatusForProcess(HANDLE process_handle);
+
+ private:
+ OSInfo();
+ ~OSInfo();
+
+ Version version_;
+ VersionNumber version_number_;
+ ServicePack service_pack_;
+ WindowsArchitecture architecture_;
+ int processors_;
+ size_t allocation_granularity_;
+ WOW64Status wow64_status_;
+
+ friend struct DefaultSingletonTraits<OSInfo>;
+ DISALLOW_COPY_AND_ASSIGN(OSInfo);
+};
-// Like GetWOW64Status(), but for the supplied handle instead of the current
-// process.
-WOW64Status GetWOW64StatusForProcess(HANDLE process_handle);
+// Because this is by far the most commonly-requested value from the above
+// singleton, we add a global-scope accessor here as syntactic sugar.
+BASE_API Version GetVersion();
} // namespace win
} // namespace base
diff --git a/base/win/wrapped_window_proc.cc b/base/win/wrapped_window_proc.cc
new file mode 100644
index 0000000..c94c5ae
--- /dev/null
+++ b/base/win/wrapped_window_proc.cc
@@ -0,0 +1,32 @@
+// Copyright (c) 2011 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.
+
+#include "base/win/wrapped_window_proc.h"
+
+#include "base/atomicops.h"
+
+namespace {
+
+base::win::WinProcExceptionFilter s_exception_filter = NULL;
+
+} // namespace.
+
+namespace base {
+namespace win {
+
+WinProcExceptionFilter SetWinProcExceptionFilter(
+ WinProcExceptionFilter filter) {
+ subtle::AtomicWord rv = subtle::NoBarrier_AtomicExchange(
+ reinterpret_cast<subtle::AtomicWord*>(&s_exception_filter),
+ reinterpret_cast<subtle::AtomicWord>(filter));
+ return reinterpret_cast<WinProcExceptionFilter>(rv);
+}
+
+int CallExceptionFilter(EXCEPTION_POINTERS* info) {
+ return s_exception_filter ? s_exception_filter(info) :
+ EXCEPTION_CONTINUE_SEARCH;
+}
+
+} // namespace win
+} // namespace base
diff --git a/base/win/wrapped_window_proc.h b/base/win/wrapped_window_proc.h
new file mode 100644
index 0000000..eac150e
--- /dev/null
+++ b/base/win/wrapped_window_proc.h
@@ -0,0 +1,69 @@
+// Copyright (c) 2011 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.
+
+// Provides a way to handle exceptions that happen while a WindowProc is
+// running. The behavior of exceptions generated inside a WindowProc is OS
+// dependent, but it is possible that the OS just ignores the exception and
+// continues execution, which leads to unpredictable behavior for Chrome.
+
+#ifndef BASE_WIN_WRAPPED_WINDOW_PROC_H_
+#define BASE_WIN_WRAPPED_WINDOW_PROC_H_
+#pragma once
+
+#include <windows.h>
+
+#include "base/base_api.h"
+
+namespace base {
+namespace win {
+
+// An exception filter for a WindowProc. The return value determines how the
+// exception should be handled, following standard SEH rules. However, the
+// expected behavior for this function is to not return, instead of returning
+// EXCEPTION_EXECUTE_HANDLER or similar, given that in general we are not
+// prepared to handle exceptions.
+typedef int (__cdecl *WinProcExceptionFilter)(EXCEPTION_POINTERS* info);
+
+// Sets the filter to deal with exceptions inside a WindowProc. Returns the old
+// exception filter, if any.
+// This function should be called before any window is created.
+BASE_API WinProcExceptionFilter SetWinProcExceptionFilter(
+ WinProcExceptionFilter filter);
+
+// Calls the registered exception filter.
+BASE_API int CallExceptionFilter(EXCEPTION_POINTERS* info);
+
+// Wrapper that supplies a standard exception frame for the provided WindowProc.
+// The normal usage is something like this:
+//
+// LRESULT CALLBACK MyWinProc(HWND hwnd, UINT message,
+// WPARAM wparam, LPARAM lparam) {
+// // Do Something.
+// }
+//
+// ...
+//
+// WNDCLASSEX wc = {0};
+// wc.lpfnWndProc = WrappedWindowProc<MyWinProc>;
+// wc.lpszClassName = class_name;
+// ...
+// RegisterClassEx(&wc);
+//
+// CreateWindowW(class_name, window_name, ...
+//
+template <WNDPROC proc>
+LRESULT CALLBACK WrappedWindowProc(HWND hwnd, UINT message,
+ WPARAM wparam, LPARAM lparam) {
+ LRESULT rv = 0;
+ __try {
+ rv = proc(hwnd, message, wparam, lparam);
+ } __except(CallExceptionFilter(GetExceptionInformation())) {
+ }
+ return rv;
+}
+
+} // namespace win
+} // namespace base
+
+#endif // BASE_WIN_WRAPPED_WINDOW_PROC_H_
diff --git a/base/win/wrapped_window_proc_unittest.cc b/base/win/wrapped_window_proc_unittest.cc
new file mode 100644
index 0000000..ccf3c85
--- /dev/null
+++ b/base/win/wrapped_window_proc_unittest.cc
@@ -0,0 +1,79 @@
+// Copyright (c) 2011 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.
+
+#include "base/win/wrapped_window_proc.h"
+#include "base/message_loop.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace {
+
+DWORD kExceptionCode = 12345;
+WPARAM kCrashMsg = 98765;
+
+// A trivial WindowProc that generates an exception.
+LRESULT CALLBACK TestWindowProc(HWND hwnd, UINT message,
+ WPARAM wparam, LPARAM lparam) {
+ if (message == kCrashMsg)
+ RaiseException(kExceptionCode, 0, 0, NULL);
+ return DefWindowProc(hwnd, message, wparam, lparam);
+}
+
+// This class implements an exception filter that can be queried about a past
+// exception.
+class TestWrappedExceptionFiter {
+ public:
+ TestWrappedExceptionFiter() : called_(false) {
+ EXPECT_FALSE(s_filter_);
+ s_filter_ = this;
+ }
+
+ ~TestWrappedExceptionFiter() {
+ EXPECT_EQ(s_filter_, this);
+ s_filter_ = NULL;
+ }
+
+ bool called() {
+ return called_;
+ }
+
+ // The actual exception filter just records the exception.
+ static int Filter(EXCEPTION_POINTERS* info) {
+ EXPECT_FALSE(s_filter_->called_);
+ if (info->ExceptionRecord->ExceptionCode == kExceptionCode)
+ s_filter_->called_ = true;
+ return EXCEPTION_EXECUTE_HANDLER;
+ }
+
+ private:
+ bool called_;
+ static TestWrappedExceptionFiter* s_filter_;
+};
+TestWrappedExceptionFiter* TestWrappedExceptionFiter::s_filter_ = NULL;
+
+} // namespace.
+
+TEST(WrappedWindowProc, CatchesExceptions) {
+ HINSTANCE hinst = GetModuleHandle(NULL);
+ std::wstring class_name(L"TestClass");
+
+ WNDCLASS wc = {0};
+ wc.lpfnWndProc = base::win::WrappedWindowProc<TestWindowProc>;
+ wc.hInstance = hinst;
+ wc.lpszClassName = class_name.c_str();
+ RegisterClass(&wc);
+
+ HWND window = CreateWindow(class_name.c_str(), 0, 0, 0, 0, 0, 0, HWND_MESSAGE,
+ 0, hinst, 0);
+ ASSERT_TRUE(window);
+
+ // Before generating the exception we make sure that the filter will see it.
+ TestWrappedExceptionFiter wrapper;
+ base::win::WinProcExceptionFilter old_filter =
+ base::win::SetWinProcExceptionFilter(TestWrappedExceptionFiter::Filter);
+
+ SendMessage(window, kCrashMsg, 0, 0);
+ EXPECT_TRUE(wrapper.called());
+
+ base::win::SetWinProcExceptionFilter(old_filter);
+}