Add base to the repository.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@8 0039d316-1c4b-4281-b951-d872f2087c98
296
base/SConscript
Normal file
@ -0,0 +1,296 @@
|
||||
# Copyright 2008, Google Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are
|
||||
# met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following disclaimer
|
||||
# in the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
# * Neither the name of Google Inc. nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Import('env')
|
||||
|
||||
env = env.Clone()
|
||||
env_tests = env.Clone()
|
||||
|
||||
env.Prepend(
|
||||
CPPPATH = [
|
||||
'$ICU38_DIR/public/common',
|
||||
'$ICU38_DIR/public/i18n',
|
||||
'..',
|
||||
],
|
||||
CPPDEFINES = [
|
||||
'U_STATIC_IMPLEMENTATION',
|
||||
'CERT_CHAIN_PARA_HAS_EXTRA_FIELDS',
|
||||
'WIN32_LEAN_AND_MEAN',
|
||||
],
|
||||
CCFLAGS = [
|
||||
'/TP',
|
||||
|
||||
'/Wp64',
|
||||
|
||||
'/wd4503',
|
||||
'/wd4819',
|
||||
],
|
||||
)
|
||||
|
||||
input_files = [
|
||||
'base_drag_source.cc',
|
||||
'base_drop_target.cc',
|
||||
'base_paths.cc',
|
||||
'base_switches.cc',
|
||||
'clipboard.cc',
|
||||
'clipboard_util.cc',
|
||||
'command_line.cc',
|
||||
'condition_variable.cc',
|
||||
'debug_on_start.cc',
|
||||
'debug_util.cc',
|
||||
'event_recorder.cc',
|
||||
'file_util.cc',
|
||||
'file_version_info.cc',
|
||||
'histogram.cc',
|
||||
'hmac.cc',
|
||||
'iat_patch.cc',
|
||||
'icu_util.cc',
|
||||
'idle_timer.cc',
|
||||
'image_util.cc',
|
||||
'json_reader.cc',
|
||||
'json_writer.cc',
|
||||
'lock.cc',
|
||||
'lock_impl_win.cc',
|
||||
'logging.cc',
|
||||
'md5.cc',
|
||||
'memory_debug.cc',
|
||||
'message_loop.cc',
|
||||
'non_thread_safe.cc',
|
||||
'path_service.cc',
|
||||
'pe_image.cc',
|
||||
'pickle.cc',
|
||||
'platform_thread.cc',
|
||||
'process.cc',
|
||||
'process_util.cc',
|
||||
'registry.cc',
|
||||
'resource_util.cc',
|
||||
'revocable_store.cc',
|
||||
'sha2.cc',
|
||||
'shared_event.cc',
|
||||
'shared_memory.cc',
|
||||
'stats_table.cc',
|
||||
'string_escape.cc',
|
||||
'string_util.cc',
|
||||
'string_util_icu.cc',
|
||||
'string_util_win.cc',
|
||||
'third_party/nspr/prtime.cc',
|
||||
'third_party/nss/sha512.cc',
|
||||
'thread.cc',
|
||||
'thread_local_storage_win.cc',
|
||||
'time.cc',
|
||||
'time_win.cc',
|
||||
'timer.cc',
|
||||
'tracked.cc',
|
||||
'tracked_objects.cc',
|
||||
'values.cc',
|
||||
'watchdog.cc',
|
||||
'win_util.cc',
|
||||
'wmi_util.cc',
|
||||
'word_iterator.cc',
|
||||
'worker_pool.cc',
|
||||
]
|
||||
|
||||
env.StaticLibrary('base', input_files)
|
||||
|
||||
|
||||
env_tests.Prepend(
|
||||
CPPPATH = [
|
||||
'$SKIA_DIR/include',
|
||||
'$SKIA_DIR/include/corecg',
|
||||
'$SKIA_DIR/platform',
|
||||
'$ZLIB_DIR',
|
||||
'$LIBPNG_DIR',
|
||||
'$ICU38_DIR/public/common',
|
||||
'$ICU38/_DIRpublic/i18n',
|
||||
'..',
|
||||
],
|
||||
CPPDEFINES = [
|
||||
'UNIT_TEST',
|
||||
'PNG_USER_CONFIG',
|
||||
'CHROME_PNG_WRITE_SUPPORT',
|
||||
'U_STATIC_IMPLEMENTATION',
|
||||
'_WIN32_WINNT=0x0600',
|
||||
'WINVER=0x0600',
|
||||
'_HAS_EXCEPTIONS=0',
|
||||
'CERT_CHAIN_PARA_HAS_EXTRA_FIELDS',
|
||||
'WIN32_LEAN_AND_MEAN',
|
||||
],
|
||||
CCFLAGS = [
|
||||
'/WX',
|
||||
'/Wp64',
|
||||
'/TP',
|
||||
|
||||
'/wd4503',
|
||||
'/wd4819',
|
||||
],
|
||||
LINKFLAGS = [
|
||||
'/MANIFEST',
|
||||
'/DELAYLOAD:"dwmapi.dll"',
|
||||
'/DELAYLOAD:"uxtheme.dll"',
|
||||
'/MACHINE:X86',
|
||||
'/FIXED:No',
|
||||
|
||||
'/safeseh',
|
||||
'/dynamicbase',
|
||||
'/ignore:4199',
|
||||
'/nxcompat',
|
||||
],
|
||||
LIBS = [
|
||||
'advapi32.lib',
|
||||
'comdlg32.lib',
|
||||
'DelayImp.lib',
|
||||
'gdi32.lib',
|
||||
'kernel32.lib',
|
||||
'msimg32.lib',
|
||||
'odbc32.lib',
|
||||
'odbccp32.lib',
|
||||
'ole32.lib',
|
||||
'oleaut32.lib',
|
||||
'psapi.lib',
|
||||
'shell32.lib',
|
||||
'user32.lib',
|
||||
'usp10.lib',
|
||||
'uuid.lib',
|
||||
'version.lib',
|
||||
'wininet.lib',
|
||||
'winspool.lib',
|
||||
'ws2_32.lib',
|
||||
],
|
||||
)
|
||||
|
||||
libs = [
|
||||
'base.lib',
|
||||
'gfx/base_gfx.lib',
|
||||
'$SKIA_DIR/skia.lib',
|
||||
'$LIBPNG_DIR/libpng.lib',
|
||||
'$TESTING_DIR/gtest.lib',
|
||||
'$ICU38_DIR/icuuc.lib',
|
||||
'$ZLIB_DIR/zlib.lib',
|
||||
]
|
||||
|
||||
env_tests.Append(
|
||||
CPPPATH = [
|
||||
'$GTEST_DIR/include',
|
||||
],
|
||||
)
|
||||
|
||||
env_tests_dll = env_tests.Clone()
|
||||
env_tests_dll.Append(
|
||||
CPPDEFINES = [
|
||||
'_WINDLL',
|
||||
'SINGLETON_UNITTEST_EXPORTS',
|
||||
],
|
||||
)
|
||||
dll = env_tests_dll.SharedLibrary(['singleton_dll_unittest.dll',
|
||||
'singleton_dll_unittest.ilk',
|
||||
'singleton_dll_unittest.pdb'],
|
||||
['singleton_dll_unittest.cc',
|
||||
'build/singleton_dll_unittest.def'] + libs)
|
||||
i = env.Install('$TARGET_ROOT', dll[0])
|
||||
env.Alias('base', i)
|
||||
|
||||
env_tests.Program(['debug_message.exe',
|
||||
'debug_message.ilk',
|
||||
'debug_message.pdb'],
|
||||
['debug_message.cc'] + libs)
|
||||
|
||||
test_files = [
|
||||
'atomic_unittest.cc',
|
||||
'check_handler_unittest.cc',
|
||||
'clipboard_unittest.cc',
|
||||
'command_line_unittest.cc',
|
||||
'condition_variable_test.cc',
|
||||
'file_util_unittest.cc',
|
||||
'file_version_info_unittest.cc',
|
||||
'fixed_string_unittest.cc',
|
||||
'gfx/convolver_unittest.cc',
|
||||
'gfx/image_operations_unittest.cc',
|
||||
'gfx/native_theme_unittest.cc',
|
||||
'gfx/platform_canvas_unittest.cc',
|
||||
'gfx/png_codec_unittest.cc',
|
||||
'gfx/rect_unittest.cc',
|
||||
'gfx/uniscribe_unittest.cc',
|
||||
'gfx/vector_canvas_unittest.cc',
|
||||
'hmac_unittest.cc',
|
||||
'json_reader_unittest.cc',
|
||||
'json_writer_unittest.cc',
|
||||
'linked_ptr_unittest.cc',
|
||||
'message_loop_unittest.cc',
|
||||
'path_service_unittest.cc',
|
||||
'pe_image_unittest.cc',
|
||||
'pickle_unittest.cc',
|
||||
'pr_time_test.cc',
|
||||
'process_util_unittest.cc',
|
||||
'ref_counted_unittest.cc',
|
||||
'run_all_unittests.cc',
|
||||
'sha2_unittest.cc',
|
||||
'shared_event_unittest.cc',
|
||||
'shared_memory_unittest.cc',
|
||||
'singleton_unittest.cc',
|
||||
'stack_container_unittest.cc',
|
||||
'stats_table_unittest.cc',
|
||||
'string_tokenizer_unittest.cc',
|
||||
'string_util_unittest.cc',
|
||||
'thread_local_storage_unittest.cc',
|
||||
'thread_unittest.cc',
|
||||
'tracked_objects_test.cc',
|
||||
'time_unittest.cc',
|
||||
'timer_unittest.cc',
|
||||
'values_unittest.cc',
|
||||
'win_util_unittest.cc',
|
||||
'wmi_util_unittest.cc',
|
||||
|
||||
'singleton_dll_unittest.lib',
|
||||
]
|
||||
|
||||
base_unittests = env_tests.Program([
|
||||
'base_unittests',
|
||||
'base_unittests.exp',
|
||||
'base_unittests.ilk',
|
||||
'base_unittests.lib',
|
||||
'base_unittests.pdb'], test_files + libs)
|
||||
|
||||
|
||||
# Install up a level to allow unit test path assumptions to be valid.
|
||||
installed_base_unittests = env.Install('$TARGET_ROOT', base_unittests)
|
||||
|
||||
|
||||
sconscript_dirs = [
|
||||
'gfx/SConscript',
|
||||
]
|
||||
|
||||
SConscript(sconscript_dirs, exports=['env'])
|
||||
|
||||
|
||||
# Setup alias for all base related targets.
|
||||
env.Alias('base', ['.', installed_base_unittests, '../icudt38.dll'])
|
||||
|
||||
|
||||
env_tests.StaticObject('perftimer.cc')
|
||||
env_tests.StaticObject('run_all_perftests.cc')
|
3
base/SConstruct
Normal file
@ -0,0 +1,3 @@
|
||||
build_component = 'base'
|
||||
SConscript('../build/SConscript.main',
|
||||
exports=['build_component'])
|
111
base/atomic.h
Normal file
@ -0,0 +1,111 @@
|
||||
// Copyright 2008, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#ifndef BASE_ATOMIC_H__
|
||||
#define BASE_ATOMIC_H__
|
||||
|
||||
#if defined(WIN32)
|
||||
#include <windows.h>
|
||||
#elif defined(__APPLE__)
|
||||
#include <libkern/OSAtomic.h>
|
||||
#else
|
||||
#error Implement atomic support on your platform
|
||||
#endif
|
||||
|
||||
#include "base/basictypes.h"
|
||||
|
||||
namespace base {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Forward declarations and descriptions of the functions
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Atomically increments *value and returns the resulting incremented value.
|
||||
// This function implies no memory barriers.
|
||||
int32 AtomicIncrement(volatile int32* value);
|
||||
|
||||
// Atomically decrements *value and returns the resulting decremented value.
|
||||
// This function implies no memory barriers.
|
||||
int32 AtomicDecrement(volatile int32* value);
|
||||
|
||||
// Atomically sets *target to new_value and returns the old value of *target.
|
||||
// This function implies no memory barriers.
|
||||
int32 AtomicSwap(volatile int32* target, int32 new_value);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Implementations for various platforms
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if defined(WIN32)
|
||||
|
||||
inline int32 AtomicIncrement(volatile int32* value) {
|
||||
return InterlockedIncrement(reinterpret_cast<volatile LONG*>(value));
|
||||
}
|
||||
|
||||
inline int32 AtomicDecrement(volatile int32* value) {
|
||||
return InterlockedDecrement(reinterpret_cast<volatile LONG*>(value));
|
||||
}
|
||||
|
||||
inline int32 AtomicSwap(volatile int32* target, int32 new_value) {
|
||||
return InterlockedExchange(reinterpret_cast<volatile LONG*>(target),
|
||||
new_value);
|
||||
}
|
||||
|
||||
#elif defined(__APPLE__)
|
||||
|
||||
inline int32 AtomicIncrement(volatile int32* value) {
|
||||
return OSAtomicIncrement32(reinterpret_cast<volatile int32_t*>(value));
|
||||
}
|
||||
|
||||
inline int32 AtomicDecrement(volatile int32* value) {
|
||||
return OSAtomicDecrement32(reinterpret_cast<volatile int32_t*>(value));
|
||||
}
|
||||
|
||||
inline int32 AtomicSwap(volatile int32* target, int32 new_value) {
|
||||
int32 old_value;
|
||||
do {
|
||||
old_value = *target;
|
||||
} while (!OSAtomicCompareAndSwap32(old_value, new_value,
|
||||
reinterpret_cast<volatile int32_t*>(target)));
|
||||
return old_value;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#error Implement atomic support on your platform
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace base
|
||||
|
||||
#endif // BASE_ATOMIC_H__
|
63
base/atomic_unittest.cc
Normal file
@ -0,0 +1,63 @@
|
||||
// Copyright 2008, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include "base/atomic.h"
|
||||
|
||||
#include "base/lock.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
|
||||
TEST(AtomicTest, Increment) {
|
||||
int32 value = 38;
|
||||
int32 new_value = base::AtomicIncrement(&value);
|
||||
EXPECT_EQ(39, value);
|
||||
EXPECT_EQ(39, new_value);
|
||||
}
|
||||
|
||||
TEST(AtomicTest, Decrement) {
|
||||
int32 value = 49;
|
||||
int32 new_value = base::AtomicDecrement(&value);
|
||||
EXPECT_EQ(48, value);
|
||||
EXPECT_EQ(48, new_value);
|
||||
}
|
||||
|
||||
TEST(AtomicTest, Swap) {
|
||||
int32 value = 38;
|
||||
int32 old_value = base::AtomicSwap(&value, 49);
|
||||
EXPECT_EQ(49, value);
|
||||
EXPECT_EQ(38, old_value);
|
||||
|
||||
// Now do another test.
|
||||
value = 0;
|
||||
old_value = base::AtomicSwap(&value, 1);
|
||||
EXPECT_EQ(0, old_value);
|
||||
old_value = base::AtomicSwap(&value, 1);
|
||||
EXPECT_EQ(1, old_value);
|
||||
old_value = base::AtomicSwap(&value, 1);
|
||||
EXPECT_EQ(1, old_value);
|
||||
}
|
109
base/base.sln
Normal file
@ -0,0 +1,109 @@
|
||||
Microsoft Visual Studio Solution File, Format Version 9.00
|
||||
# Visual Studio 2005
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "base", "build\base.vcproj", "{1832A374-8A74-4F9E-B536-69A699B3E165}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{0E5474AC-5996-4B13-87C0-4AE931EE0815} = {0E5474AC-5996-4B13-87C0-4AE931EE0815}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "base_unittests", "build\base_unittests.vcproj", "{27A30967-4BBA-48D1-8522-CDE95F7B1CEC}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{1832A374-8A74-4F9E-B536-69A699B3E165} = {1832A374-8A74-4F9E-B536-69A699B3E165}
|
||||
{8423AF0D-4B88-4EBF-94E1-E4D00D00E21C} = {8423AF0D-4B88-4EBF-94E1-E4D00D00E21C}
|
||||
{8C27D792-2648-4F5E-9ED0-374276327308} = {8C27D792-2648-4F5E-9ED0-374276327308}
|
||||
{A508ADD3-CECE-4E0F-8448-2F5E454DF551} = {A508ADD3-CECE-4E0F-8448-2F5E454DF551}
|
||||
{BFE8E2A7-3B3B-43B0-A994-3058B852DB8B} = {BFE8E2A7-3B3B-43B0-A994-3058B852DB8B}
|
||||
{C564F145-9172-42C3-BFCB-6014CA97DBCD} = {C564F145-9172-42C3-BFCB-6014CA97DBCD}
|
||||
{CD9CA56E-4E94-444C-87D4-58CA1E6F300D} = {CD9CA56E-4E94-444C-87D4-58CA1E6F300D}
|
||||
{E457F2FB-4708-4001-9B1C-275D7BD7F2A8} = {E457F2FB-4708-4001-9B1C-275D7BD7F2A8}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "debug_message", "build\debug_message.vcproj", "{0E5474AC-5996-4B13-87C0-4AE931EE0815}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "dependencies", "dependencies", "{F216062D-F9C4-4883-A52C-2BE9ECADEEA0}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "icuuc", "..\third_party\icu38\build\icuuc.vcproj", "{8C27D792-2648-4F5E-9ED0-374276327308}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{A0D94973-D355-47A5-A1E2-3456F321F010} = {A0D94973-D355-47A5-A1E2-3456F321F010}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "icudt", "..\third_party\icu38\build\icudt.vcproj", "{A0D94973-D355-47A5-A1E2-3456F321F010}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "base_gfx", "build\base_gfx.vcproj", "{A508ADD3-CECE-4E0F-8448-2F5E454DF551}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "skia", "..\skia\skia.vcproj", "{CD9CA56E-4E94-444C-87D4-58CA1E6F300D}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libpng", "..\third_party\libpng\libpng.vcproj", "{C564F145-9172-42C3-BFCB-6014CA97DBCD}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlib", "..\third_party\zlib\zlib.vcproj", "{8423AF0D-4B88-4EBF-94E1-E4D00D00E21C}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "singleton_dll_unittest", "build\singleton_unittest.vcproj", "{E457F2FB-4708-4001-9B1C-275D7BD7F2A8}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{1832A374-8A74-4F9E-B536-69A699B3E165} = {1832A374-8A74-4F9E-B536-69A699B3E165}
|
||||
{8C27D792-2648-4F5E-9ED0-374276327308} = {8C27D792-2648-4F5E-9ED0-374276327308}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest", "..\testing\gtest.vcproj", "{BFE8E2A7-3B3B-43B0-A994-3058B852DB8B}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Release|Win32 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{0E5474AC-5996-4B13-87C0-4AE931EE0815}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{0E5474AC-5996-4B13-87C0-4AE931EE0815}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{0E5474AC-5996-4B13-87C0-4AE931EE0815}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{0E5474AC-5996-4B13-87C0-4AE931EE0815}.Release|Win32.Build.0 = Release|Win32
|
||||
{1832A374-8A74-4F9E-B536-69A699B3E165}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{1832A374-8A74-4F9E-B536-69A699B3E165}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{1832A374-8A74-4F9E-B536-69A699B3E165}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{1832A374-8A74-4F9E-B536-69A699B3E165}.Release|Win32.Build.0 = Release|Win32
|
||||
{27A30967-4BBA-48D1-8522-CDE95F7B1CEC}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{27A30967-4BBA-48D1-8522-CDE95F7B1CEC}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{27A30967-4BBA-48D1-8522-CDE95F7B1CEC}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{27A30967-4BBA-48D1-8522-CDE95F7B1CEC}.Release|Win32.Build.0 = Release|Win32
|
||||
{8423AF0D-4B88-4EBF-94E1-E4D00D00E21C}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{8423AF0D-4B88-4EBF-94E1-E4D00D00E21C}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{8423AF0D-4B88-4EBF-94E1-E4D00D00E21C}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{8423AF0D-4B88-4EBF-94E1-E4D00D00E21C}.Release|Win32.Build.0 = Release|Win32
|
||||
{8C27D792-2648-4F5E-9ED0-374276327308}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{8C27D792-2648-4F5E-9ED0-374276327308}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{8C27D792-2648-4F5E-9ED0-374276327308}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{8C27D792-2648-4F5E-9ED0-374276327308}.Release|Win32.Build.0 = Release|Win32
|
||||
{A0D94973-D355-47A5-A1E2-3456F321F010}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{A0D94973-D355-47A5-A1E2-3456F321F010}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{A0D94973-D355-47A5-A1E2-3456F321F010}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{A0D94973-D355-47A5-A1E2-3456F321F010}.Release|Win32.Build.0 = Release|Win32
|
||||
{A508ADD3-CECE-4E0F-8448-2F5E454DF551}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{A508ADD3-CECE-4E0F-8448-2F5E454DF551}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{A508ADD3-CECE-4E0F-8448-2F5E454DF551}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{A508ADD3-CECE-4E0F-8448-2F5E454DF551}.Release|Win32.Build.0 = Release|Win32
|
||||
{BFE8E2A7-3B3B-43B0-A994-3058B852DB8B}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{BFE8E2A7-3B3B-43B0-A994-3058B852DB8B}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{BFE8E2A7-3B3B-43B0-A994-3058B852DB8B}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{BFE8E2A7-3B3B-43B0-A994-3058B852DB8B}.Release|Win32.Build.0 = Release|Win32
|
||||
{C564F145-9172-42C3-BFCB-6014CA97DBCD}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{C564F145-9172-42C3-BFCB-6014CA97DBCD}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{C564F145-9172-42C3-BFCB-6014CA97DBCD}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{C564F145-9172-42C3-BFCB-6014CA97DBCD}.Release|Win32.Build.0 = Release|Win32
|
||||
{CD9CA56E-4E94-444C-87D4-58CA1E6F300D}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{CD9CA56E-4E94-444C-87D4-58CA1E6F300D}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{CD9CA56E-4E94-444C-87D4-58CA1E6F300D}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{CD9CA56E-4E94-444C-87D4-58CA1E6F300D}.Release|Win32.Build.0 = Release|Win32
|
||||
{E457F2FB-4708-4001-9B1C-275D7BD7F2A8}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{E457F2FB-4708-4001-9B1C-275D7BD7F2A8}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{E457F2FB-4708-4001-9B1C-275D7BD7F2A8}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{E457F2FB-4708-4001-9B1C-275D7BD7F2A8}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{8423AF0D-4B88-4EBF-94E1-E4D00D00E21C} = {F216062D-F9C4-4883-A52C-2BE9ECADEEA0}
|
||||
{8C27D792-2648-4F5E-9ED0-374276327308} = {F216062D-F9C4-4883-A52C-2BE9ECADEEA0}
|
||||
{A0D94973-D355-47A5-A1E2-3456F321F010} = {F216062D-F9C4-4883-A52C-2BE9ECADEEA0}
|
||||
{BFE8E2A7-3B3B-43B0-A994-3058B852DB8B} = {F216062D-F9C4-4883-A52C-2BE9ECADEEA0}
|
||||
{C564F145-9172-42C3-BFCB-6014CA97DBCD} = {F216062D-F9C4-4883-A52C-2BE9ECADEEA0}
|
||||
{CD9CA56E-4E94-444C-87D4-58CA1E6F300D} = {F216062D-F9C4-4883-A52C-2BE9ECADEEA0}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
970
base/base.xcodeproj/project.pbxproj
Normal file
@ -0,0 +1,970 @@
|
||||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 42;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXAggregateTarget section */
|
||||
825404020D92D3340006B936 /* All */ = {
|
||||
isa = PBXAggregateTarget;
|
||||
buildConfigurationList = 825404110D92D35C0006B936 /* Build configuration list for PBXAggregateTarget "All" */;
|
||||
buildPhases = (
|
||||
);
|
||||
dependencies = (
|
||||
825404060D92D33A0006B936 /* PBXTargetDependency */,
|
||||
825404080D92D33C0006B936 /* PBXTargetDependency */,
|
||||
);
|
||||
name = All;
|
||||
productName = All;
|
||||
};
|
||||
/* End PBXAggregateTarget section */
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
7B5AD60E0D9DD8050012BCF1 /* scoped_cftyperef.h in Headers */ = {isa = PBXBuildFile; fileRef = 7B5AD60D0D9DD8050012BCF1 /* scoped_cftyperef.h */; };
|
||||
7BD9E84F0DA447F800FC7A01 /* singleton.h in Headers */ = {isa = PBXBuildFile; fileRef = 7BD9E84E0DA447F800FC7A01 /* singleton.h */; };
|
||||
7BEB81110D9AD288009BA8DD /* prcpucfg_mac.h in Headers */ = {isa = PBXBuildFile; fileRef = 7BEB81100D9AD288009BA8DD /* prcpucfg_mac.h */; };
|
||||
7BEB814A0D9B0F33009BA8DD /* time_mac.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7BEB81490D9B0F33009BA8DD /* time_mac.cc */; };
|
||||
7BEB834E0D9C4BE0009BA8DD /* string_util_mac.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7BEB834D0D9C4BE0009BA8DD /* string_util_mac.cc */; };
|
||||
7BEE52C20D9D84FD0067FF23 /* string_util_mac.h in Headers */ = {isa = PBXBuildFile; fileRef = 7BEE52C10D9D84FD0067FF23 /* string_util_mac.h */; };
|
||||
7BEFC29E0D99832D000829AD /* lock_impl.h in Headers */ = {isa = PBXBuildFile; fileRef = 7BEFC29C0D99832D000829AD /* lock_impl.h */; };
|
||||
7BEFC29F0D99832D000829AD /* lock_impl_mac.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7BEFC29D0D99832D000829AD /* lock_impl_mac.cc */; };
|
||||
821B91690DAABD7F00F350D7 /* string16.h in Headers */ = {isa = PBXBuildFile; fileRef = 821B91680DAABD7F00F350D7 /* string16.h */; };
|
||||
825402CE0D92D1390006B936 /* base_drag_source.cc in Sources */ = {isa = PBXBuildFile; fileRef = 825402C50D92D1390006B936 /* base_drag_source.cc */; };
|
||||
825402CF0D92D1390006B936 /* base_drag_source.h in Headers */ = {isa = PBXBuildFile; fileRef = 825402C60D92D1390006B936 /* base_drag_source.h */; };
|
||||
825402D00D92D1390006B936 /* base_drop_target.cc in Sources */ = {isa = PBXBuildFile; fileRef = 825402C70D92D1390006B936 /* base_drop_target.cc */; };
|
||||
825402D10D92D1390006B936 /* base_drop_target.h in Headers */ = {isa = PBXBuildFile; fileRef = 825402C80D92D1390006B936 /* base_drop_target.h */; };
|
||||
825402D20D92D1390006B936 /* base_paths.cc in Sources */ = {isa = PBXBuildFile; fileRef = 825402C90D92D1390006B936 /* base_paths.cc */; };
|
||||
825402D30D92D1390006B936 /* base_paths.h in Headers */ = {isa = PBXBuildFile; fileRef = 825402CA0D92D1390006B936 /* base_paths.h */; };
|
||||
825402D40D92D1390006B936 /* base_switches.cc in Sources */ = {isa = PBXBuildFile; fileRef = 825402CB0D92D1390006B936 /* base_switches.cc */; };
|
||||
825402D50D92D1390006B936 /* base_switches.h in Headers */ = {isa = PBXBuildFile; fileRef = 825402CC0D92D1390006B936 /* base_switches.h */; };
|
||||
825402D60D92D1390006B936 /* basictypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 825402CD0D92D1390006B936 /* basictypes.h */; };
|
||||
825402D90D92D15E0006B936 /* blapi.h in Headers */ = {isa = PBXBuildFile; fileRef = 825402D70D92D15E0006B936 /* blapi.h */; };
|
||||
825402DA0D92D15E0006B936 /* blapit.h in Headers */ = {isa = PBXBuildFile; fileRef = 825402D80D92D15E0006B936 /* blapit.h */; };
|
||||
825402DF0D92D1730006B936 /* clipboard.h in Headers */ = {isa = PBXBuildFile; fileRef = 825402DB0D92D1730006B936 /* clipboard.h */; };
|
||||
825402E00D92D1730006B936 /* clipboard.cc in Sources */ = {isa = PBXBuildFile; fileRef = 825402DC0D92D1730006B936 /* clipboard.cc */; };
|
||||
825402E10D92D1730006B936 /* clipboard_util.h in Headers */ = {isa = PBXBuildFile; fileRef = 825402DD0D92D1730006B936 /* clipboard_util.h */; };
|
||||
825402E20D92D1730006B936 /* clipboard_util.cc in Sources */ = {isa = PBXBuildFile; fileRef = 825402DE0D92D1730006B936 /* clipboard_util.cc */; };
|
||||
825402E50D92D1850006B936 /* command_line.cc in Sources */ = {isa = PBXBuildFile; fileRef = 825402E30D92D1850006B936 /* command_line.cc */; };
|
||||
825402E60D92D1850006B936 /* command_line.h in Headers */ = {isa = PBXBuildFile; fileRef = 825402E40D92D1850006B936 /* command_line.h */; };
|
||||
825402EE0D92D1940006B936 /* condition_variable.h in Headers */ = {isa = PBXBuildFile; fileRef = 825402EB0D92D1940006B936 /* condition_variable.h */; };
|
||||
825402EF0D92D1940006B936 /* condition_variable.cc in Sources */ = {isa = PBXBuildFile; fileRef = 825402EC0D92D1940006B936 /* condition_variable.cc */; };
|
||||
825402F00D92D1940006B936 /* condition_variable_events.h in Headers */ = {isa = PBXBuildFile; fileRef = 825402ED0D92D1940006B936 /* condition_variable_events.h */; };
|
||||
825402F50D92D1AC0006B936 /* debug_util.h in Headers */ = {isa = PBXBuildFile; fileRef = 825402F10D92D1AC0006B936 /* debug_util.h */; };
|
||||
825402F60D92D1AC0006B936 /* debug_util.cc in Sources */ = {isa = PBXBuildFile; fileRef = 825402F20D92D1AC0006B936 /* debug_util.cc */; };
|
||||
825402F70D92D1AC0006B936 /* debug_on_start.h in Headers */ = {isa = PBXBuildFile; fileRef = 825402F30D92D1AC0006B936 /* debug_on_start.h */; };
|
||||
825402F80D92D1AC0006B936 /* debug_on_start.cc in Sources */ = {isa = PBXBuildFile; fileRef = 825402F40D92D1AC0006B936 /* debug_on_start.cc */; };
|
||||
825403010D92D1BC0006B936 /* event_recorder.cc in Sources */ = {isa = PBXBuildFile; fileRef = 825402FF0D92D1BC0006B936 /* event_recorder.cc */; };
|
||||
825403020D92D1BC0006B936 /* event_recorder.h in Headers */ = {isa = PBXBuildFile; fileRef = 825403000D92D1BC0006B936 /* event_recorder.h */; };
|
||||
825403050D92D1C50006B936 /* file_util.h in Headers */ = {isa = PBXBuildFile; fileRef = 825403030D92D1C50006B936 /* file_util.h */; };
|
||||
825403060D92D1C50006B936 /* file_util.cc in Sources */ = {isa = PBXBuildFile; fileRef = 825403040D92D1C50006B936 /* file_util.cc */; };
|
||||
825403090D92D1CD0006B936 /* file_version_info.h in Headers */ = {isa = PBXBuildFile; fileRef = 825403070D92D1CD0006B936 /* file_version_info.h */; };
|
||||
8254030A0D92D1CD0006B936 /* file_version_info.cc in Sources */ = {isa = PBXBuildFile; fileRef = 825403080D92D1CD0006B936 /* file_version_info.cc */; };
|
||||
8254030C0D92D1D10006B936 /* fix_wp64.h in Headers */ = {isa = PBXBuildFile; fileRef = 8254030B0D92D1D10006B936 /* fix_wp64.h */; };
|
||||
8254030E0D92D1DB0006B936 /* fixed_string.h in Headers */ = {isa = PBXBuildFile; fileRef = 8254030D0D92D1DB0006B936 /* fixed_string.h */; };
|
||||
825403140D92D1E80006B936 /* iat_patch.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8254030F0D92D1E80006B936 /* iat_patch.cc */; };
|
||||
825403150D92D1E80006B936 /* iat_patch.h in Headers */ = {isa = PBXBuildFile; fileRef = 825403100D92D1E80006B936 /* iat_patch.h */; };
|
||||
825403160D92D1E80006B936 /* icu_util.cc in Sources */ = {isa = PBXBuildFile; fileRef = 825403110D92D1E80006B936 /* icu_util.cc */; };
|
||||
825403170D92D1E80006B936 /* icu_util.h in Headers */ = {isa = PBXBuildFile; fileRef = 825403120D92D1E80006B936 /* icu_util.h */; };
|
||||
825403180D92D1E80006B936 /* id_map.h in Headers */ = {isa = PBXBuildFile; fileRef = 825403130D92D1E80006B936 /* id_map.h */; };
|
||||
8254031F0D92D1F40006B936 /* image_util.cc in Sources */ = {isa = PBXBuildFile; fileRef = 825403190D92D1F40006B936 /* image_util.cc */; };
|
||||
825403200D92D1F40006B936 /* image_util.h in Headers */ = {isa = PBXBuildFile; fileRef = 8254031A0D92D1F40006B936 /* image_util.h */; };
|
||||
825403210D92D1F40006B936 /* json_reader.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8254031B0D92D1F40006B936 /* json_reader.cc */; };
|
||||
825403220D92D1F40006B936 /* json_reader.h in Headers */ = {isa = PBXBuildFile; fileRef = 8254031C0D92D1F40006B936 /* json_reader.h */; };
|
||||
825403230D92D1F40006B936 /* json_writer.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8254031D0D92D1F40006B936 /* json_writer.cc */; };
|
||||
825403240D92D1F40006B936 /* json_writer.h in Headers */ = {isa = PBXBuildFile; fileRef = 8254031E0D92D1F40006B936 /* json_writer.h */; };
|
||||
8254032D0D92D2090006B936 /* lock.cc in Sources */ = {isa = PBXBuildFile; fileRef = 825403250D92D2090006B936 /* lock.cc */; };
|
||||
8254032E0D92D2090006B936 /* lock.h in Headers */ = {isa = PBXBuildFile; fileRef = 825403260D92D2090006B936 /* lock.h */; };
|
||||
8254032F0D92D2090006B936 /* logging.cc in Sources */ = {isa = PBXBuildFile; fileRef = 825403270D92D2090006B936 /* logging.cc */; };
|
||||
825403300D92D2090006B936 /* logging.h in Headers */ = {isa = PBXBuildFile; fileRef = 825403280D92D2090006B936 /* logging.h */; };
|
||||
825403310D92D2090006B936 /* md5.cc in Sources */ = {isa = PBXBuildFile; fileRef = 825403290D92D2090006B936 /* md5.cc */; };
|
||||
825403320D92D2090006B936 /* md5.h in Headers */ = {isa = PBXBuildFile; fileRef = 8254032A0D92D2090006B936 /* md5.h */; };
|
||||
825403330D92D2090006B936 /* memory_debug.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8254032B0D92D2090006B936 /* memory_debug.cc */; };
|
||||
825403340D92D2090006B936 /* memory_debug.h in Headers */ = {isa = PBXBuildFile; fileRef = 8254032C0D92D2090006B936 /* memory_debug.h */; };
|
||||
825403370D92D2110006B936 /* message_loop.cc in Sources */ = {isa = PBXBuildFile; fileRef = 825403350D92D2110006B936 /* message_loop.cc */; };
|
||||
825403380D92D2110006B936 /* message_loop.h in Headers */ = {isa = PBXBuildFile; fileRef = 825403360D92D2110006B936 /* message_loop.h */; };
|
||||
825403410D92D2210006B936 /* observer_list.h in Headers */ = {isa = PBXBuildFile; fileRef = 825403390D92D2210006B936 /* observer_list.h */; };
|
||||
825403420D92D2210006B936 /* path_service.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8254033A0D92D2210006B936 /* path_service.cc */; };
|
||||
825403430D92D2210006B936 /* path_service.h in Headers */ = {isa = PBXBuildFile; fileRef = 8254033B0D92D2210006B936 /* path_service.h */; };
|
||||
825403440D92D2210006B936 /* pe_image.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8254033C0D92D2210006B936 /* pe_image.cc */; };
|
||||
825403450D92D2210006B936 /* pe_image.h in Headers */ = {isa = PBXBuildFile; fileRef = 8254033D0D92D2210006B936 /* pe_image.h */; };
|
||||
825403460D92D2210006B936 /* pickle.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8254033E0D92D2210006B936 /* pickle.cc */; };
|
||||
825403470D92D2210006B936 /* pickle.h in Headers */ = {isa = PBXBuildFile; fileRef = 8254033F0D92D2210006B936 /* pickle.h */; };
|
||||
825403480D92D2210006B936 /* port.h in Headers */ = {isa = PBXBuildFile; fileRef = 825403400D92D2210006B936 /* port.h */; };
|
||||
8254034D0D92D23C0006B936 /* prtypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 825403490D92D23C0006B936 /* prtypes.h */; };
|
||||
8254034E0D92D23C0006B936 /* prtime.h in Headers */ = {isa = PBXBuildFile; fileRef = 8254034A0D92D23C0006B936 /* prtime.h */; };
|
||||
8254034F0D92D23C0006B936 /* prtime.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8254034B0D92D23C0006B936 /* prtime.cc */; };
|
||||
825403500D92D23C0006B936 /* prcpucfg.h in Headers */ = {isa = PBXBuildFile; fileRef = 8254034C0D92D23C0006B936 /* prcpucfg.h */; };
|
||||
825403530D92D24D0006B936 /* process_util.h in Headers */ = {isa = PBXBuildFile; fileRef = 825403510D92D24D0006B936 /* process_util.h */; };
|
||||
825403540D92D24D0006B936 /* process_util.cc in Sources */ = {isa = PBXBuildFile; fileRef = 825403520D92D24D0006B936 /* process_util.cc */; };
|
||||
825403560D92D2580006B936 /* pure.h in Headers */ = {isa = PBXBuildFile; fileRef = 825403550D92D2580006B936 /* pure.h */; };
|
||||
825403580D92D25E0006B936 /* pure_api.c in Sources */ = {isa = PBXBuildFile; fileRef = 825403570D92D25E0006B936 /* pure_api.c */; };
|
||||
825403640D92D27C0006B936 /* ref_counted.h in Headers */ = {isa = PBXBuildFile; fileRef = 825403590D92D27C0006B936 /* ref_counted.h */; };
|
||||
825403650D92D27C0006B936 /* registry.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8254035A0D92D27C0006B936 /* registry.cc */; };
|
||||
825403660D92D27C0006B936 /* registry.h in Headers */ = {isa = PBXBuildFile; fileRef = 8254035B0D92D27C0006B936 /* registry.h */; };
|
||||
825403670D92D27C0006B936 /* resource_util.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8254035C0D92D27C0006B936 /* resource_util.cc */; };
|
||||
825403680D92D27C0006B936 /* resource_util.h in Headers */ = {isa = PBXBuildFile; fileRef = 8254035D0D92D27C0006B936 /* resource_util.h */; };
|
||||
825403690D92D27C0006B936 /* revocable_store.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8254035E0D92D27C0006B936 /* revocable_store.cc */; };
|
||||
8254036A0D92D27C0006B936 /* revocable_store.h in Headers */ = {isa = PBXBuildFile; fileRef = 8254035F0D92D27C0006B936 /* revocable_store.h */; };
|
||||
8254036C0D92D27C0006B936 /* scoped_ptr.h in Headers */ = {isa = PBXBuildFile; fileRef = 825403610D92D27C0006B936 /* scoped_ptr.h */; };
|
||||
8254036D0D92D27C0006B936 /* sha2.cc in Sources */ = {isa = PBXBuildFile; fileRef = 825403620D92D27C0006B936 /* sha2.cc */; };
|
||||
8254036E0D92D27C0006B936 /* sha2.h in Headers */ = {isa = PBXBuildFile; fileRef = 825403630D92D27C0006B936 /* sha2.h */; };
|
||||
825403710D92D2840006B936 /* sha256.h in Headers */ = {isa = PBXBuildFile; fileRef = 8254036F0D92D2840006B936 /* sha256.h */; };
|
||||
825403720D92D2840006B936 /* sha512.cc in Sources */ = {isa = PBXBuildFile; fileRef = 825403700D92D2840006B936 /* sha512.cc */; };
|
||||
825403900D92D2CF0006B936 /* shared_event.cc in Sources */ = {isa = PBXBuildFile; fileRef = 825403730D92D2CF0006B936 /* shared_event.cc */; };
|
||||
825403910D92D2CF0006B936 /* shared_event.h in Headers */ = {isa = PBXBuildFile; fileRef = 825403740D92D2CF0006B936 /* shared_event.h */; };
|
||||
825403920D92D2CF0006B936 /* shared_memory.cc in Sources */ = {isa = PBXBuildFile; fileRef = 825403750D92D2CF0006B936 /* shared_memory.cc */; };
|
||||
825403930D92D2CF0006B936 /* shared_memory.h in Headers */ = {isa = PBXBuildFile; fileRef = 825403760D92D2CF0006B936 /* shared_memory.h */; };
|
||||
825403940D92D2CF0006B936 /* stack_container.h in Headers */ = {isa = PBXBuildFile; fileRef = 825403770D92D2CF0006B936 /* stack_container.h */; };
|
||||
825403950D92D2CF0006B936 /* stats_counters.h in Headers */ = {isa = PBXBuildFile; fileRef = 825403780D92D2CF0006B936 /* stats_counters.h */; };
|
||||
825403960D92D2CF0006B936 /* stats_table.cc in Sources */ = {isa = PBXBuildFile; fileRef = 825403790D92D2CF0006B936 /* stats_table.cc */; };
|
||||
825403970D92D2CF0006B936 /* stats_table.h in Headers */ = {isa = PBXBuildFile; fileRef = 8254037A0D92D2CF0006B936 /* stats_table.h */; };
|
||||
825403980D92D2CF0006B936 /* string_tokenizer.h in Headers */ = {isa = PBXBuildFile; fileRef = 8254037B0D92D2CF0006B936 /* string_tokenizer.h */; };
|
||||
825403990D92D2CF0006B936 /* string_util.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8254037C0D92D2CF0006B936 /* string_util.cc */; };
|
||||
8254039A0D92D2CF0006B936 /* string_util.h in Headers */ = {isa = PBXBuildFile; fileRef = 8254037D0D92D2CF0006B936 /* string_util.h */; };
|
||||
8254039B0D92D2CF0006B936 /* task.h in Headers */ = {isa = PBXBuildFile; fileRef = 8254037E0D92D2CF0006B936 /* task.h */; };
|
||||
8254039C0D92D2CF0006B936 /* thread.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8254037F0D92D2CF0006B936 /* thread.cc */; };
|
||||
8254039D0D92D2CF0006B936 /* thread.h in Headers */ = {isa = PBXBuildFile; fileRef = 825403800D92D2CF0006B936 /* thread.h */; };
|
||||
8254039E0D92D2CF0006B936 /* thread_local_storage.cc in Sources */ = {isa = PBXBuildFile; fileRef = 825403810D92D2CF0006B936 /* thread_local_storage.cc */; };
|
||||
8254039F0D92D2CF0006B936 /* thread_local_storage.h in Headers */ = {isa = PBXBuildFile; fileRef = 825403820D92D2CF0006B936 /* thread_local_storage.h */; };
|
||||
825403A00D92D2CF0006B936 /* time.cc in Sources */ = {isa = PBXBuildFile; fileRef = 825403830D92D2CF0006B936 /* time.cc */; };
|
||||
825403A10D92D2CF0006B936 /* time.h in Headers */ = {isa = PBXBuildFile; fileRef = 825403840D92D2CF0006B936 /* time.h */; };
|
||||
825403A20D92D2CF0006B936 /* timer.cc in Sources */ = {isa = PBXBuildFile; fileRef = 825403850D92D2CF0006B936 /* timer.cc */; };
|
||||
825403A30D92D2CF0006B936 /* timer.h in Headers */ = {isa = PBXBuildFile; fileRef = 825403860D92D2CF0006B936 /* timer.h */; };
|
||||
825403A40D92D2CF0006B936 /* tuple.h in Headers */ = {isa = PBXBuildFile; fileRef = 825403870D92D2CF0006B936 /* tuple.h */; };
|
||||
825403A50D92D2CF0006B936 /* values.cc in Sources */ = {isa = PBXBuildFile; fileRef = 825403880D92D2CF0006B936 /* values.cc */; };
|
||||
825403A60D92D2CF0006B936 /* values.h in Headers */ = {isa = PBXBuildFile; fileRef = 825403890D92D2CF0006B936 /* values.h */; };
|
||||
825403A70D92D2CF0006B936 /* win_util.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8254038A0D92D2CF0006B936 /* win_util.cc */; };
|
||||
825403A80D92D2CF0006B936 /* win_util.h in Headers */ = {isa = PBXBuildFile; fileRef = 8254038B0D92D2CF0006B936 /* win_util.h */; };
|
||||
825403A90D92D2CF0006B936 /* wmi_util.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8254038C0D92D2CF0006B936 /* wmi_util.cc */; };
|
||||
825403AA0D92D2CF0006B936 /* wmi_util.h in Headers */ = {isa = PBXBuildFile; fileRef = 8254038D0D92D2CF0006B936 /* wmi_util.h */; };
|
||||
825403AB0D92D2CF0006B936 /* word_iterator.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8254038E0D92D2CF0006B936 /* word_iterator.cc */; };
|
||||
825403AC0D92D2CF0006B936 /* word_iterator.h in Headers */ = {isa = PBXBuildFile; fileRef = 8254038F0D92D2CF0006B936 /* word_iterator.h */; };
|
||||
825403E10D92D31D0006B936 /* bitmap_header.cc in Sources */ = {isa = PBXBuildFile; fileRef = 825403C00D92D31D0006B936 /* bitmap_header.cc */; };
|
||||
825403E20D92D31D0006B936 /* bitmap_header.h in Headers */ = {isa = PBXBuildFile; fileRef = 825403C10D92D31D0006B936 /* bitmap_header.h */; };
|
||||
825403E30D92D31D0006B936 /* bitmap_platform_device.cc in Sources */ = {isa = PBXBuildFile; fileRef = 825403C20D92D31D0006B936 /* bitmap_platform_device.cc */; };
|
||||
825403E40D92D31D0006B936 /* bitmap_platform_device.h in Headers */ = {isa = PBXBuildFile; fileRef = 825403C30D92D31D0006B936 /* bitmap_platform_device.h */; };
|
||||
825403E50D92D31D0006B936 /* font_utils.cc in Sources */ = {isa = PBXBuildFile; fileRef = 825403C40D92D31D0006B936 /* font_utils.cc */; };
|
||||
825403E60D92D31D0006B936 /* font_utils.h in Headers */ = {isa = PBXBuildFile; fileRef = 825403C50D92D31D0006B936 /* font_utils.h */; };
|
||||
825403E70D92D31D0006B936 /* image_resizer.cc in Sources */ = {isa = PBXBuildFile; fileRef = 825403C60D92D31D0006B936 /* image_resizer.cc */; };
|
||||
825403E80D92D31D0006B936 /* image_resizer.h in Headers */ = {isa = PBXBuildFile; fileRef = 825403C70D92D31D0006B936 /* image_resizer.h */; };
|
||||
825403E90D92D31D0006B936 /* native_theme.cc in Sources */ = {isa = PBXBuildFile; fileRef = 825403C80D92D31D0006B936 /* native_theme.cc */; };
|
||||
825403EA0D92D31D0006B936 /* native_theme.h in Headers */ = {isa = PBXBuildFile; fileRef = 825403C90D92D31D0006B936 /* native_theme.h */; };
|
||||
825403EB0D92D31D0006B936 /* platform_canvas.h in Headers */ = {isa = PBXBuildFile; fileRef = 825403CA0D92D31D0006B936 /* platform_canvas.h */; };
|
||||
825403EC0D92D31D0006B936 /* platform_device.cc in Sources */ = {isa = PBXBuildFile; fileRef = 825403CB0D92D31D0006B936 /* platform_device.cc */; };
|
||||
825403ED0D92D31D0006B936 /* platform_device.h in Headers */ = {isa = PBXBuildFile; fileRef = 825403CC0D92D31D0006B936 /* platform_device.h */; };
|
||||
825403EE0D92D31D0006B936 /* png_decoder.cc in Sources */ = {isa = PBXBuildFile; fileRef = 825403CD0D92D31D0006B936 /* png_decoder.cc */; };
|
||||
825403EF0D92D31D0006B936 /* png_decoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 825403CE0D92D31D0006B936 /* png_decoder.h */; };
|
||||
825403F00D92D31D0006B936 /* png_encoder.cc in Sources */ = {isa = PBXBuildFile; fileRef = 825403CF0D92D31D0006B936 /* png_encoder.cc */; };
|
||||
825403F10D92D31D0006B936 /* png_encoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 825403D00D92D31D0006B936 /* png_encoder.h */; };
|
||||
825403F20D92D31D0006B936 /* point.cc in Sources */ = {isa = PBXBuildFile; fileRef = 825403D10D92D31D0006B936 /* point.cc */; };
|
||||
825403F30D92D31D0006B936 /* point.h in Headers */ = {isa = PBXBuildFile; fileRef = 825403D20D92D31D0006B936 /* point.h */; };
|
||||
825403F40D92D31D0006B936 /* rect_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 825403D30D92D31D0006B936 /* rect_unittest.cc */; };
|
||||
825403F50D92D31D0006B936 /* rect.cc in Sources */ = {isa = PBXBuildFile; fileRef = 825403D40D92D31D0006B936 /* rect.cc */; };
|
||||
825403F60D92D31D0006B936 /* rect.h in Headers */ = {isa = PBXBuildFile; fileRef = 825403D50D92D31D0006B936 /* rect.h */; };
|
||||
825403F70D92D31D0006B936 /* size.cc in Sources */ = {isa = PBXBuildFile; fileRef = 825403D60D92D31D0006B936 /* size.cc */; };
|
||||
825403F80D92D31D0006B936 /* size.h in Headers */ = {isa = PBXBuildFile; fileRef = 825403D70D92D31D0006B936 /* size.h */; };
|
||||
825403F90D92D31D0006B936 /* skia_utils.cc in Sources */ = {isa = PBXBuildFile; fileRef = 825403D80D92D31D0006B936 /* skia_utils.cc */; };
|
||||
825403FA0D92D31D0006B936 /* skia_utils.h in Headers */ = {isa = PBXBuildFile; fileRef = 825403D90D92D31D0006B936 /* skia_utils.h */; };
|
||||
825403FB0D92D31D0006B936 /* uniscribe.cc in Sources */ = {isa = PBXBuildFile; fileRef = 825403DA0D92D31D0006B936 /* uniscribe.cc */; };
|
||||
825403FC0D92D31D0006B936 /* uniscribe.h in Headers */ = {isa = PBXBuildFile; fileRef = 825403DB0D92D31D0006B936 /* uniscribe.h */; };
|
||||
825403FD0D92D31D0006B936 /* vector_canvas.cc in Sources */ = {isa = PBXBuildFile; fileRef = 825403DC0D92D31D0006B936 /* vector_canvas.cc */; };
|
||||
825403FE0D92D31D0006B936 /* vector_canvas.h in Headers */ = {isa = PBXBuildFile; fileRef = 825403DD0D92D31D0006B936 /* vector_canvas.h */; };
|
||||
825403FF0D92D31D0006B936 /* vector_device.cc in Sources */ = {isa = PBXBuildFile; fileRef = 825403DE0D92D31D0006B936 /* vector_device.cc */; };
|
||||
825404000D92D31D0006B936 /* vector_device.h in Headers */ = {isa = PBXBuildFile; fileRef = 825403DF0D92D31D0006B936 /* vector_device.h */; };
|
||||
825404010D92D31D0006B936 /* platform_canvas.cc in Sources */ = {isa = PBXBuildFile; fileRef = 825403E00D92D31D0006B936 /* platform_canvas.cc */; };
|
||||
82E23FCD0D9C219600F8B40A /* platform_thread.h in Headers */ = {isa = PBXBuildFile; fileRef = 82E23FCB0D9C219600F8B40A /* platform_thread.h */; };
|
||||
82E23FCE0D9C219600F8B40A /* platform_thread.cc in Sources */ = {isa = PBXBuildFile; fileRef = 82E23FCC0D9C219600F8B40A /* platform_thread.cc */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
825404050D92D33A0006B936 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 825402AA0D92D0C60006B936 /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = 825402BA0D92D0FA0006B936;
|
||||
remoteInfo = base;
|
||||
};
|
||||
825404070D92D33C0006B936 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 825402AA0D92D0C60006B936 /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = 825403B00D92D2E50006B936;
|
||||
remoteInfo = base_gfx;
|
||||
};
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
7B5AD60D0D9DD8050012BCF1 /* scoped_cftyperef.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = scoped_cftyperef.h; sourceTree = "<group>"; };
|
||||
7BD9E84E0DA447F800FC7A01 /* singleton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = singleton.h; sourceTree = "<group>"; };
|
||||
7BEB81100D9AD288009BA8DD /* prcpucfg_mac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = prcpucfg_mac.h; path = third_party/nspr/prcpucfg_mac.h; sourceTree = "<group>"; };
|
||||
7BEB81490D9B0F33009BA8DD /* time_mac.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = time_mac.cc; sourceTree = "<group>"; };
|
||||
7BEB834D0D9C4BE0009BA8DD /* string_util_mac.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = string_util_mac.cc; sourceTree = "<group>"; };
|
||||
7BEE52C10D9D84FD0067FF23 /* string_util_mac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = string_util_mac.h; sourceTree = "<group>"; };
|
||||
7BEFC29C0D99832D000829AD /* lock_impl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lock_impl.h; sourceTree = "<group>"; };
|
||||
7BEFC29D0D99832D000829AD /* lock_impl_mac.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = lock_impl_mac.cc; sourceTree = "<group>"; };
|
||||
821B91680DAABD7F00F350D7 /* string16.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = string16.h; sourceTree = "<group>"; };
|
||||
825402BB0D92D0FA0006B936 /* libbase.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libbase.a; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
825402C50D92D1390006B936 /* base_drag_source.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = base_drag_source.cc; sourceTree = "<group>"; };
|
||||
825402C60D92D1390006B936 /* base_drag_source.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = base_drag_source.h; sourceTree = "<group>"; };
|
||||
825402C70D92D1390006B936 /* base_drop_target.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = base_drop_target.cc; sourceTree = "<group>"; };
|
||||
825402C80D92D1390006B936 /* base_drop_target.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = base_drop_target.h; sourceTree = "<group>"; };
|
||||
825402C90D92D1390006B936 /* base_paths.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = base_paths.cc; sourceTree = "<group>"; };
|
||||
825402CA0D92D1390006B936 /* base_paths.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = base_paths.h; sourceTree = "<group>"; };
|
||||
825402CB0D92D1390006B936 /* base_switches.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = base_switches.cc; sourceTree = "<group>"; };
|
||||
825402CC0D92D1390006B936 /* base_switches.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = base_switches.h; sourceTree = "<group>"; };
|
||||
825402CD0D92D1390006B936 /* basictypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = basictypes.h; sourceTree = "<group>"; };
|
||||
825402D70D92D15E0006B936 /* blapi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = blapi.h; path = third_party/nss/blapi.h; sourceTree = "<group>"; };
|
||||
825402D80D92D15E0006B936 /* blapit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = blapit.h; path = third_party/nss/blapit.h; sourceTree = "<group>"; };
|
||||
825402DB0D92D1730006B936 /* clipboard.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = clipboard.h; sourceTree = "<group>"; };
|
||||
825402DC0D92D1730006B936 /* clipboard.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = clipboard.cc; sourceTree = "<group>"; };
|
||||
825402DD0D92D1730006B936 /* clipboard_util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = clipboard_util.h; sourceTree = "<group>"; };
|
||||
825402DE0D92D1730006B936 /* clipboard_util.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = clipboard_util.cc; sourceTree = "<group>"; };
|
||||
825402E30D92D1850006B936 /* command_line.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = command_line.cc; sourceTree = "<group>"; };
|
||||
825402E40D92D1850006B936 /* command_line.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = command_line.h; sourceTree = "<group>"; };
|
||||
825402EB0D92D1940006B936 /* condition_variable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = condition_variable.h; sourceTree = "<group>"; };
|
||||
825402EC0D92D1940006B936 /* condition_variable.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = condition_variable.cc; sourceTree = "<group>"; };
|
||||
825402ED0D92D1940006B936 /* condition_variable_events.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = condition_variable_events.h; sourceTree = "<group>"; };
|
||||
825402F10D92D1AC0006B936 /* debug_util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debug_util.h; sourceTree = "<group>"; };
|
||||
825402F20D92D1AC0006B936 /* debug_util.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = debug_util.cc; sourceTree = "<group>"; };
|
||||
825402F30D92D1AC0006B936 /* debug_on_start.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debug_on_start.h; sourceTree = "<group>"; };
|
||||
825402F40D92D1AC0006B936 /* debug_on_start.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = debug_on_start.cc; sourceTree = "<group>"; };
|
||||
825402FF0D92D1BC0006B936 /* event_recorder.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = event_recorder.cc; sourceTree = "<group>"; };
|
||||
825403000D92D1BC0006B936 /* event_recorder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = event_recorder.h; sourceTree = "<group>"; };
|
||||
825403030D92D1C50006B936 /* file_util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = file_util.h; sourceTree = "<group>"; };
|
||||
825403040D92D1C50006B936 /* file_util.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = file_util.cc; sourceTree = "<group>"; };
|
||||
825403070D92D1CD0006B936 /* file_version_info.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = file_version_info.h; sourceTree = "<group>"; };
|
||||
825403080D92D1CD0006B936 /* file_version_info.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = file_version_info.cc; sourceTree = "<group>"; };
|
||||
8254030B0D92D1D10006B936 /* fix_wp64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fix_wp64.h; sourceTree = "<group>"; };
|
||||
8254030D0D92D1DB0006B936 /* fixed_string.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fixed_string.h; sourceTree = "<group>"; };
|
||||
8254030F0D92D1E80006B936 /* iat_patch.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = iat_patch.cc; sourceTree = "<group>"; };
|
||||
825403100D92D1E80006B936 /* iat_patch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iat_patch.h; sourceTree = "<group>"; };
|
||||
825403110D92D1E80006B936 /* icu_util.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = icu_util.cc; sourceTree = "<group>"; };
|
||||
825403120D92D1E80006B936 /* icu_util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = icu_util.h; sourceTree = "<group>"; };
|
||||
825403130D92D1E80006B936 /* id_map.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = id_map.h; sourceTree = "<group>"; };
|
||||
825403190D92D1F40006B936 /* image_util.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = image_util.cc; sourceTree = "<group>"; };
|
||||
8254031A0D92D1F40006B936 /* image_util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = image_util.h; sourceTree = "<group>"; };
|
||||
8254031B0D92D1F40006B936 /* json_reader.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = json_reader.cc; sourceTree = "<group>"; };
|
||||
8254031C0D92D1F40006B936 /* json_reader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = json_reader.h; sourceTree = "<group>"; };
|
||||
8254031D0D92D1F40006B936 /* json_writer.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = json_writer.cc; sourceTree = "<group>"; };
|
||||
8254031E0D92D1F40006B936 /* json_writer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = json_writer.h; sourceTree = "<group>"; };
|
||||
825403250D92D2090006B936 /* lock.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = lock.cc; sourceTree = "<group>"; };
|
||||
825403260D92D2090006B936 /* lock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lock.h; sourceTree = "<group>"; };
|
||||
825403270D92D2090006B936 /* logging.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = logging.cc; sourceTree = "<group>"; };
|
||||
825403280D92D2090006B936 /* logging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = logging.h; sourceTree = "<group>"; };
|
||||
825403290D92D2090006B936 /* md5.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = md5.cc; sourceTree = "<group>"; };
|
||||
8254032A0D92D2090006B936 /* md5.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = md5.h; sourceTree = "<group>"; };
|
||||
8254032B0D92D2090006B936 /* memory_debug.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = memory_debug.cc; sourceTree = "<group>"; };
|
||||
8254032C0D92D2090006B936 /* memory_debug.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = memory_debug.h; sourceTree = "<group>"; };
|
||||
825403350D92D2110006B936 /* message_loop.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = message_loop.cc; sourceTree = "<group>"; };
|
||||
825403360D92D2110006B936 /* message_loop.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = message_loop.h; sourceTree = "<group>"; };
|
||||
825403390D92D2210006B936 /* observer_list.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = observer_list.h; sourceTree = "<group>"; };
|
||||
8254033A0D92D2210006B936 /* path_service.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = path_service.cc; sourceTree = "<group>"; };
|
||||
8254033B0D92D2210006B936 /* path_service.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = path_service.h; sourceTree = "<group>"; };
|
||||
8254033C0D92D2210006B936 /* pe_image.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = pe_image.cc; sourceTree = "<group>"; };
|
||||
8254033D0D92D2210006B936 /* pe_image.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pe_image.h; sourceTree = "<group>"; };
|
||||
8254033E0D92D2210006B936 /* pickle.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = pickle.cc; sourceTree = "<group>"; };
|
||||
8254033F0D92D2210006B936 /* pickle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pickle.h; sourceTree = "<group>"; };
|
||||
825403400D92D2210006B936 /* port.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = port.h; sourceTree = "<group>"; };
|
||||
825403490D92D23C0006B936 /* prtypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = prtypes.h; path = third_party/nspr/prtypes.h; sourceTree = "<group>"; };
|
||||
8254034A0D92D23C0006B936 /* prtime.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = prtime.h; path = third_party/nspr/prtime.h; sourceTree = "<group>"; };
|
||||
8254034B0D92D23C0006B936 /* prtime.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = prtime.cc; path = third_party/nspr/prtime.cc; sourceTree = "<group>"; };
|
||||
8254034C0D92D23C0006B936 /* prcpucfg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = prcpucfg.h; path = third_party/nspr/prcpucfg.h; sourceTree = "<group>"; };
|
||||
825403510D92D24D0006B936 /* process_util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = process_util.h; sourceTree = "<group>"; };
|
||||
825403520D92D24D0006B936 /* process_util.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = process_util.cc; sourceTree = "<group>"; };
|
||||
825403550D92D2580006B936 /* pure.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = pure.h; path = third_party/purify/pure.h; sourceTree = "<group>"; };
|
||||
825403570D92D25E0006B936 /* pure_api.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pure_api.c; path = third_party/purify/pure_api.c; sourceTree = "<group>"; };
|
||||
825403590D92D27C0006B936 /* ref_counted.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ref_counted.h; sourceTree = "<group>"; };
|
||||
8254035A0D92D27C0006B936 /* registry.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = registry.cc; sourceTree = "<group>"; };
|
||||
8254035B0D92D27C0006B936 /* registry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = registry.h; sourceTree = "<group>"; };
|
||||
8254035C0D92D27C0006B936 /* resource_util.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = resource_util.cc; sourceTree = "<group>"; };
|
||||
8254035D0D92D27C0006B936 /* resource_util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = resource_util.h; sourceTree = "<group>"; };
|
||||
8254035E0D92D27C0006B936 /* revocable_store.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = revocable_store.cc; sourceTree = "<group>"; };
|
||||
8254035F0D92D27C0006B936 /* revocable_store.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = revocable_store.h; sourceTree = "<group>"; };
|
||||
825403610D92D27C0006B936 /* scoped_ptr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = scoped_ptr.h; sourceTree = "<group>"; };
|
||||
825403620D92D27C0006B936 /* sha2.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sha2.cc; sourceTree = "<group>"; };
|
||||
825403630D92D27C0006B936 /* sha2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sha2.h; sourceTree = "<group>"; };
|
||||
8254036F0D92D2840006B936 /* sha256.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = sha256.h; path = third_party/nss/sha256.h; sourceTree = "<group>"; };
|
||||
825403700D92D2840006B936 /* sha512.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = sha512.cc; path = third_party/nss/sha512.cc; sourceTree = "<group>"; };
|
||||
825403730D92D2CF0006B936 /* shared_event.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = shared_event.cc; sourceTree = "<group>"; };
|
||||
825403740D92D2CF0006B936 /* shared_event.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = shared_event.h; sourceTree = "<group>"; };
|
||||
825403750D92D2CF0006B936 /* shared_memory.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = shared_memory.cc; sourceTree = "<group>"; };
|
||||
825403760D92D2CF0006B936 /* shared_memory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = shared_memory.h; sourceTree = "<group>"; };
|
||||
825403770D92D2CF0006B936 /* stack_container.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = stack_container.h; sourceTree = "<group>"; };
|
||||
825403780D92D2CF0006B936 /* stats_counters.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = stats_counters.h; sourceTree = "<group>"; };
|
||||
825403790D92D2CF0006B936 /* stats_table.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = stats_table.cc; sourceTree = "<group>"; };
|
||||
8254037A0D92D2CF0006B936 /* stats_table.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = stats_table.h; sourceTree = "<group>"; };
|
||||
8254037B0D92D2CF0006B936 /* string_tokenizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = string_tokenizer.h; sourceTree = "<group>"; };
|
||||
8254037C0D92D2CF0006B936 /* string_util.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = string_util.cc; sourceTree = "<group>"; };
|
||||
8254037D0D92D2CF0006B936 /* string_util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = string_util.h; sourceTree = "<group>"; };
|
||||
8254037E0D92D2CF0006B936 /* task.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = task.h; sourceTree = "<group>"; };
|
||||
8254037F0D92D2CF0006B936 /* thread.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = thread.cc; sourceTree = "<group>"; };
|
||||
825403800D92D2CF0006B936 /* thread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = thread.h; sourceTree = "<group>"; };
|
||||
825403810D92D2CF0006B936 /* thread_local_storage.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = thread_local_storage.cc; sourceTree = "<group>"; };
|
||||
825403820D92D2CF0006B936 /* thread_local_storage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = thread_local_storage.h; sourceTree = "<group>"; };
|
||||
825403830D92D2CF0006B936 /* time.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = time.cc; sourceTree = "<group>"; };
|
||||
825403840D92D2CF0006B936 /* time.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = time.h; sourceTree = "<group>"; };
|
||||
825403850D92D2CF0006B936 /* timer.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = timer.cc; sourceTree = "<group>"; };
|
||||
825403860D92D2CF0006B936 /* timer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = timer.h; sourceTree = "<group>"; };
|
||||
825403870D92D2CF0006B936 /* tuple.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tuple.h; sourceTree = "<group>"; };
|
||||
825403880D92D2CF0006B936 /* values.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = values.cc; sourceTree = "<group>"; };
|
||||
825403890D92D2CF0006B936 /* values.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = values.h; sourceTree = "<group>"; };
|
||||
8254038A0D92D2CF0006B936 /* win_util.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = win_util.cc; sourceTree = "<group>"; };
|
||||
8254038B0D92D2CF0006B936 /* win_util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = win_util.h; sourceTree = "<group>"; };
|
||||
8254038C0D92D2CF0006B936 /* wmi_util.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wmi_util.cc; sourceTree = "<group>"; };
|
||||
8254038D0D92D2CF0006B936 /* wmi_util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wmi_util.h; sourceTree = "<group>"; };
|
||||
8254038E0D92D2CF0006B936 /* word_iterator.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = word_iterator.cc; sourceTree = "<group>"; };
|
||||
8254038F0D92D2CF0006B936 /* word_iterator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = word_iterator.h; sourceTree = "<group>"; };
|
||||
825403B10D92D2E50006B936 /* libbase_gfx.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libbase_gfx.a; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
825403C00D92D31D0006B936 /* bitmap_header.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = bitmap_header.cc; sourceTree = "<group>"; };
|
||||
825403C10D92D31D0006B936 /* bitmap_header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bitmap_header.h; sourceTree = "<group>"; };
|
||||
825403C20D92D31D0006B936 /* bitmap_platform_device.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = bitmap_platform_device.cc; sourceTree = "<group>"; };
|
||||
825403C30D92D31D0006B936 /* bitmap_platform_device.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bitmap_platform_device.h; sourceTree = "<group>"; };
|
||||
825403C40D92D31D0006B936 /* font_utils.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = font_utils.cc; sourceTree = "<group>"; };
|
||||
825403C50D92D31D0006B936 /* font_utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = font_utils.h; sourceTree = "<group>"; };
|
||||
825403C60D92D31D0006B936 /* image_resizer.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = image_resizer.cc; sourceTree = "<group>"; };
|
||||
825403C70D92D31D0006B936 /* image_resizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = image_resizer.h; sourceTree = "<group>"; };
|
||||
825403C80D92D31D0006B936 /* native_theme.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = native_theme.cc; sourceTree = "<group>"; };
|
||||
825403C90D92D31D0006B936 /* native_theme.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = native_theme.h; sourceTree = "<group>"; };
|
||||
825403CA0D92D31D0006B936 /* platform_canvas.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = platform_canvas.h; sourceTree = "<group>"; };
|
||||
825403CB0D92D31D0006B936 /* platform_device.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = platform_device.cc; sourceTree = "<group>"; };
|
||||
825403CC0D92D31D0006B936 /* platform_device.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = platform_device.h; sourceTree = "<group>"; };
|
||||
825403CD0D92D31D0006B936 /* png_decoder.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = png_decoder.cc; sourceTree = "<group>"; };
|
||||
825403CE0D92D31D0006B936 /* png_decoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = png_decoder.h; sourceTree = "<group>"; };
|
||||
825403CF0D92D31D0006B936 /* png_encoder.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = png_encoder.cc; sourceTree = "<group>"; };
|
||||
825403D00D92D31D0006B936 /* png_encoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = png_encoder.h; sourceTree = "<group>"; };
|
||||
825403D10D92D31D0006B936 /* point.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = point.cc; sourceTree = "<group>"; };
|
||||
825403D20D92D31D0006B936 /* point.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = point.h; sourceTree = "<group>"; };
|
||||
825403D30D92D31D0006B936 /* rect_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = rect_unittest.cc; sourceTree = "<group>"; };
|
||||
825403D40D92D31D0006B936 /* rect.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = rect.cc; sourceTree = "<group>"; };
|
||||
825403D50D92D31D0006B936 /* rect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rect.h; sourceTree = "<group>"; };
|
||||
825403D60D92D31D0006B936 /* size.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = size.cc; sourceTree = "<group>"; };
|
||||
825403D70D92D31D0006B936 /* size.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = size.h; sourceTree = "<group>"; };
|
||||
825403D80D92D31D0006B936 /* skia_utils.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = skia_utils.cc; sourceTree = "<group>"; };
|
||||
825403D90D92D31D0006B936 /* skia_utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = skia_utils.h; sourceTree = "<group>"; };
|
||||
825403DA0D92D31D0006B936 /* uniscribe.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = uniscribe.cc; sourceTree = "<group>"; };
|
||||
825403DB0D92D31D0006B936 /* uniscribe.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uniscribe.h; sourceTree = "<group>"; };
|
||||
825403DC0D92D31D0006B936 /* vector_canvas.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = vector_canvas.cc; sourceTree = "<group>"; };
|
||||
825403DD0D92D31D0006B936 /* vector_canvas.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vector_canvas.h; sourceTree = "<group>"; };
|
||||
825403DE0D92D31D0006B936 /* vector_device.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = vector_device.cc; sourceTree = "<group>"; };
|
||||
825403DF0D92D31D0006B936 /* vector_device.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vector_device.h; sourceTree = "<group>"; };
|
||||
825403E00D92D31D0006B936 /* platform_canvas.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = platform_canvas.cc; sourceTree = "<group>"; };
|
||||
82E23FCB0D9C219600F8B40A /* platform_thread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = platform_thread.h; sourceTree = "<group>"; };
|
||||
82E23FCC0D9C219600F8B40A /* platform_thread.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = platform_thread.cc; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
825402B90D92D0FA0006B936 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
825403AF0D92D2E50006B936 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
825402A80D92D0C60006B936 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
825402B60D92D0E20006B936 /* base */,
|
||||
825403B40D92D2EC0006B936 /* base_gfx */,
|
||||
825402BC0D92D0FA0006B936 /* Products */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
825402B60D92D0E20006B936 /* base */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
825402C50D92D1390006B936 /* base_drag_source.cc */,
|
||||
825402C60D92D1390006B936 /* base_drag_source.h */,
|
||||
825402C70D92D1390006B936 /* base_drop_target.cc */,
|
||||
825402C80D92D1390006B936 /* base_drop_target.h */,
|
||||
825402C90D92D1390006B936 /* base_paths.cc */,
|
||||
825402CA0D92D1390006B936 /* base_paths.h */,
|
||||
825402CB0D92D1390006B936 /* base_switches.cc */,
|
||||
825402CC0D92D1390006B936 /* base_switches.h */,
|
||||
825402CD0D92D1390006B936 /* basictypes.h */,
|
||||
825402D70D92D15E0006B936 /* blapi.h */,
|
||||
825402D80D92D15E0006B936 /* blapit.h */,
|
||||
825402DB0D92D1730006B936 /* clipboard.h */,
|
||||
825402DC0D92D1730006B936 /* clipboard.cc */,
|
||||
825402DD0D92D1730006B936 /* clipboard_util.h */,
|
||||
825402DE0D92D1730006B936 /* clipboard_util.cc */,
|
||||
825402E40D92D1850006B936 /* command_line.h */,
|
||||
825402E30D92D1850006B936 /* command_line.cc */,
|
||||
825402EB0D92D1940006B936 /* condition_variable.h */,
|
||||
825402EC0D92D1940006B936 /* condition_variable.cc */,
|
||||
825402ED0D92D1940006B936 /* condition_variable_events.h */,
|
||||
825402F30D92D1AC0006B936 /* debug_on_start.h */,
|
||||
825402F40D92D1AC0006B936 /* debug_on_start.cc */,
|
||||
825402F10D92D1AC0006B936 /* debug_util.h */,
|
||||
825402F20D92D1AC0006B936 /* debug_util.cc */,
|
||||
825402FF0D92D1BC0006B936 /* event_recorder.cc */,
|
||||
825403000D92D1BC0006B936 /* event_recorder.h */,
|
||||
825403030D92D1C50006B936 /* file_util.h */,
|
||||
825403040D92D1C50006B936 /* file_util.cc */,
|
||||
825403070D92D1CD0006B936 /* file_version_info.h */,
|
||||
825403080D92D1CD0006B936 /* file_version_info.cc */,
|
||||
8254030B0D92D1D10006B936 /* fix_wp64.h */,
|
||||
8254030D0D92D1DB0006B936 /* fixed_string.h */,
|
||||
8254030F0D92D1E80006B936 /* iat_patch.cc */,
|
||||
825403100D92D1E80006B936 /* iat_patch.h */,
|
||||
825403110D92D1E80006B936 /* icu_util.cc */,
|
||||
825403120D92D1E80006B936 /* icu_util.h */,
|
||||
825403130D92D1E80006B936 /* id_map.h */,
|
||||
825403190D92D1F40006B936 /* image_util.cc */,
|
||||
8254031A0D92D1F40006B936 /* image_util.h */,
|
||||
8254031B0D92D1F40006B936 /* json_reader.cc */,
|
||||
8254031C0D92D1F40006B936 /* json_reader.h */,
|
||||
8254031D0D92D1F40006B936 /* json_writer.cc */,
|
||||
8254031E0D92D1F40006B936 /* json_writer.h */,
|
||||
825403250D92D2090006B936 /* lock.cc */,
|
||||
825403260D92D2090006B936 /* lock.h */,
|
||||
7BEFC29C0D99832D000829AD /* lock_impl.h */,
|
||||
7BEFC29D0D99832D000829AD /* lock_impl_mac.cc */,
|
||||
825403270D92D2090006B936 /* logging.cc */,
|
||||
825403280D92D2090006B936 /* logging.h */,
|
||||
825403290D92D2090006B936 /* md5.cc */,
|
||||
8254032A0D92D2090006B936 /* md5.h */,
|
||||
8254032B0D92D2090006B936 /* memory_debug.cc */,
|
||||
8254032C0D92D2090006B936 /* memory_debug.h */,
|
||||
825403350D92D2110006B936 /* message_loop.cc */,
|
||||
825403360D92D2110006B936 /* message_loop.h */,
|
||||
825403390D92D2210006B936 /* observer_list.h */,
|
||||
8254033A0D92D2210006B936 /* path_service.cc */,
|
||||
8254033B0D92D2210006B936 /* path_service.h */,
|
||||
8254033C0D92D2210006B936 /* pe_image.cc */,
|
||||
8254033D0D92D2210006B936 /* pe_image.h */,
|
||||
8254033E0D92D2210006B936 /* pickle.cc */,
|
||||
8254033F0D92D2210006B936 /* pickle.h */,
|
||||
82E23FCB0D9C219600F8B40A /* platform_thread.h */,
|
||||
82E23FCC0D9C219600F8B40A /* platform_thread.cc */,
|
||||
825403400D92D2210006B936 /* port.h */,
|
||||
825403490D92D23C0006B936 /* prtypes.h */,
|
||||
825403510D92D24D0006B936 /* process_util.h */,
|
||||
825403520D92D24D0006B936 /* process_util.cc */,
|
||||
8254034A0D92D23C0006B936 /* prtime.h */,
|
||||
8254034B0D92D23C0006B936 /* prtime.cc */,
|
||||
8254034C0D92D23C0006B936 /* prcpucfg.h */,
|
||||
7BEB81100D9AD288009BA8DD /* prcpucfg_mac.h */,
|
||||
825403550D92D2580006B936 /* pure.h */,
|
||||
825403570D92D25E0006B936 /* pure_api.c */,
|
||||
825403590D92D27C0006B936 /* ref_counted.h */,
|
||||
8254035A0D92D27C0006B936 /* registry.cc */,
|
||||
8254035B0D92D27C0006B936 /* registry.h */,
|
||||
8254035C0D92D27C0006B936 /* resource_util.cc */,
|
||||
8254035D0D92D27C0006B936 /* resource_util.h */,
|
||||
8254035E0D92D27C0006B936 /* revocable_store.cc */,
|
||||
8254035F0D92D27C0006B936 /* revocable_store.h */,
|
||||
7B5AD60D0D9DD8050012BCF1 /* scoped_cftyperef.h */,
|
||||
825403610D92D27C0006B936 /* scoped_ptr.h */,
|
||||
825403620D92D27C0006B936 /* sha2.cc */,
|
||||
825403630D92D27C0006B936 /* sha2.h */,
|
||||
8254036F0D92D2840006B936 /* sha256.h */,
|
||||
825403700D92D2840006B936 /* sha512.cc */,
|
||||
825403730D92D2CF0006B936 /* shared_event.cc */,
|
||||
825403740D92D2CF0006B936 /* shared_event.h */,
|
||||
825403750D92D2CF0006B936 /* shared_memory.cc */,
|
||||
825403760D92D2CF0006B936 /* shared_memory.h */,
|
||||
7BD9E84E0DA447F800FC7A01 /* singleton.h */,
|
||||
825403770D92D2CF0006B936 /* stack_container.h */,
|
||||
825403780D92D2CF0006B936 /* stats_counters.h */,
|
||||
825403790D92D2CF0006B936 /* stats_table.cc */,
|
||||
8254037A0D92D2CF0006B936 /* stats_table.h */,
|
||||
8254037B0D92D2CF0006B936 /* string_tokenizer.h */,
|
||||
8254037C0D92D2CF0006B936 /* string_util.cc */,
|
||||
8254037D0D92D2CF0006B936 /* string_util.h */,
|
||||
7BEB834D0D9C4BE0009BA8DD /* string_util_mac.cc */,
|
||||
7BEE52C10D9D84FD0067FF23 /* string_util_mac.h */,
|
||||
821B91680DAABD7F00F350D7 /* string16.h */,
|
||||
8254037E0D92D2CF0006B936 /* task.h */,
|
||||
8254037F0D92D2CF0006B936 /* thread.cc */,
|
||||
825403800D92D2CF0006B936 /* thread.h */,
|
||||
825403810D92D2CF0006B936 /* thread_local_storage.cc */,
|
||||
825403820D92D2CF0006B936 /* thread_local_storage.h */,
|
||||
825403830D92D2CF0006B936 /* time.cc */,
|
||||
825403840D92D2CF0006B936 /* time.h */,
|
||||
7BEB81490D9B0F33009BA8DD /* time_mac.cc */,
|
||||
825403850D92D2CF0006B936 /* timer.cc */,
|
||||
825403860D92D2CF0006B936 /* timer.h */,
|
||||
825403870D92D2CF0006B936 /* tuple.h */,
|
||||
825403880D92D2CF0006B936 /* values.cc */,
|
||||
825403890D92D2CF0006B936 /* values.h */,
|
||||
8254038A0D92D2CF0006B936 /* win_util.cc */,
|
||||
8254038B0D92D2CF0006B936 /* win_util.h */,
|
||||
8254038C0D92D2CF0006B936 /* wmi_util.cc */,
|
||||
8254038D0D92D2CF0006B936 /* wmi_util.h */,
|
||||
8254038E0D92D2CF0006B936 /* word_iterator.cc */,
|
||||
8254038F0D92D2CF0006B936 /* word_iterator.h */,
|
||||
);
|
||||
name = base;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
825402BC0D92D0FA0006B936 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
825402BB0D92D0FA0006B936 /* libbase.a */,
|
||||
825403B10D92D2E50006B936 /* libbase_gfx.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
825403B40D92D2EC0006B936 /* base_gfx */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
825403C00D92D31D0006B936 /* bitmap_header.cc */,
|
||||
825403C10D92D31D0006B936 /* bitmap_header.h */,
|
||||
825403C20D92D31D0006B936 /* bitmap_platform_device.cc */,
|
||||
825403C30D92D31D0006B936 /* bitmap_platform_device.h */,
|
||||
825403C40D92D31D0006B936 /* font_utils.cc */,
|
||||
825403C50D92D31D0006B936 /* font_utils.h */,
|
||||
825403C60D92D31D0006B936 /* image_resizer.cc */,
|
||||
825403C70D92D31D0006B936 /* image_resizer.h */,
|
||||
825403C80D92D31D0006B936 /* native_theme.cc */,
|
||||
825403C90D92D31D0006B936 /* native_theme.h */,
|
||||
825403CA0D92D31D0006B936 /* platform_canvas.h */,
|
||||
825403CB0D92D31D0006B936 /* platform_device.cc */,
|
||||
825403CC0D92D31D0006B936 /* platform_device.h */,
|
||||
825403CD0D92D31D0006B936 /* png_decoder.cc */,
|
||||
825403CE0D92D31D0006B936 /* png_decoder.h */,
|
||||
825403CF0D92D31D0006B936 /* png_encoder.cc */,
|
||||
825403D00D92D31D0006B936 /* png_encoder.h */,
|
||||
825403D10D92D31D0006B936 /* point.cc */,
|
||||
825403D20D92D31D0006B936 /* point.h */,
|
||||
825403D30D92D31D0006B936 /* rect_unittest.cc */,
|
||||
825403D40D92D31D0006B936 /* rect.cc */,
|
||||
825403D50D92D31D0006B936 /* rect.h */,
|
||||
825403D60D92D31D0006B936 /* size.cc */,
|
||||
825403D70D92D31D0006B936 /* size.h */,
|
||||
825403D80D92D31D0006B936 /* skia_utils.cc */,
|
||||
825403D90D92D31D0006B936 /* skia_utils.h */,
|
||||
825403DA0D92D31D0006B936 /* uniscribe.cc */,
|
||||
825403DB0D92D31D0006B936 /* uniscribe.h */,
|
||||
825403DC0D92D31D0006B936 /* vector_canvas.cc */,
|
||||
825403DD0D92D31D0006B936 /* vector_canvas.h */,
|
||||
825403DE0D92D31D0006B936 /* vector_device.cc */,
|
||||
825403DF0D92D31D0006B936 /* vector_device.h */,
|
||||
825403E00D92D31D0006B936 /* platform_canvas.cc */,
|
||||
);
|
||||
name = base_gfx;
|
||||
path = gfx;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXHeadersBuildPhase section */
|
||||
825402B70D92D0FA0006B936 /* Headers */ = {
|
||||
isa = PBXHeadersBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
825402CF0D92D1390006B936 /* base_drag_source.h in Headers */,
|
||||
825402D10D92D1390006B936 /* base_drop_target.h in Headers */,
|
||||
825402D30D92D1390006B936 /* base_paths.h in Headers */,
|
||||
825402D50D92D1390006B936 /* base_switches.h in Headers */,
|
||||
825402D60D92D1390006B936 /* basictypes.h in Headers */,
|
||||
825402D90D92D15E0006B936 /* blapi.h in Headers */,
|
||||
825402DA0D92D15E0006B936 /* blapit.h in Headers */,
|
||||
825402DF0D92D1730006B936 /* clipboard.h in Headers */,
|
||||
825402E10D92D1730006B936 /* clipboard_util.h in Headers */,
|
||||
825402E60D92D1850006B936 /* command_line.h in Headers */,
|
||||
825402EE0D92D1940006B936 /* condition_variable.h in Headers */,
|
||||
825402F00D92D1940006B936 /* condition_variable_events.h in Headers */,
|
||||
825402F50D92D1AC0006B936 /* debug_util.h in Headers */,
|
||||
825402F70D92D1AC0006B936 /* debug_on_start.h in Headers */,
|
||||
825403020D92D1BC0006B936 /* event_recorder.h in Headers */,
|
||||
825403050D92D1C50006B936 /* file_util.h in Headers */,
|
||||
825403090D92D1CD0006B936 /* file_version_info.h in Headers */,
|
||||
8254030C0D92D1D10006B936 /* fix_wp64.h in Headers */,
|
||||
8254030E0D92D1DB0006B936 /* fixed_string.h in Headers */,
|
||||
825403150D92D1E80006B936 /* iat_patch.h in Headers */,
|
||||
825403170D92D1E80006B936 /* icu_util.h in Headers */,
|
||||
825403180D92D1E80006B936 /* id_map.h in Headers */,
|
||||
825403200D92D1F40006B936 /* image_util.h in Headers */,
|
||||
825403220D92D1F40006B936 /* json_reader.h in Headers */,
|
||||
825403240D92D1F40006B936 /* json_writer.h in Headers */,
|
||||
8254032E0D92D2090006B936 /* lock.h in Headers */,
|
||||
7BEFC29E0D99832D000829AD /* lock_impl.h in Headers */,
|
||||
825403300D92D2090006B936 /* logging.h in Headers */,
|
||||
825403320D92D2090006B936 /* md5.h in Headers */,
|
||||
825403340D92D2090006B936 /* memory_debug.h in Headers */,
|
||||
825403380D92D2110006B936 /* message_loop.h in Headers */,
|
||||
825403410D92D2210006B936 /* observer_list.h in Headers */,
|
||||
825403430D92D2210006B936 /* path_service.h in Headers */,
|
||||
825403450D92D2210006B936 /* pe_image.h in Headers */,
|
||||
825403470D92D2210006B936 /* pickle.h in Headers */,
|
||||
82E23FCD0D9C219600F8B40A /* platform_thread.h in Headers */,
|
||||
825403480D92D2210006B936 /* port.h in Headers */,
|
||||
8254034D0D92D23C0006B936 /* prtypes.h in Headers */,
|
||||
8254034E0D92D23C0006B936 /* prtime.h in Headers */,
|
||||
825403500D92D23C0006B936 /* prcpucfg.h in Headers */,
|
||||
7BEB81110D9AD288009BA8DD /* prcpucfg_mac.h in Headers */,
|
||||
825403530D92D24D0006B936 /* process_util.h in Headers */,
|
||||
825403560D92D2580006B936 /* pure.h in Headers */,
|
||||
825403640D92D27C0006B936 /* ref_counted.h in Headers */,
|
||||
825403660D92D27C0006B936 /* registry.h in Headers */,
|
||||
825403680D92D27C0006B936 /* resource_util.h in Headers */,
|
||||
8254036A0D92D27C0006B936 /* revocable_store.h in Headers */,
|
||||
7B5AD60E0D9DD8050012BCF1 /* scoped_cftyperef.h in Headers */,
|
||||
8254036C0D92D27C0006B936 /* scoped_ptr.h in Headers */,
|
||||
8254036E0D92D27C0006B936 /* sha2.h in Headers */,
|
||||
825403710D92D2840006B936 /* sha256.h in Headers */,
|
||||
825403910D92D2CF0006B936 /* shared_event.h in Headers */,
|
||||
825403930D92D2CF0006B936 /* shared_memory.h in Headers */,
|
||||
7BD9E84F0DA447F800FC7A01 /* singleton.h in Headers */,
|
||||
825403940D92D2CF0006B936 /* stack_container.h in Headers */,
|
||||
825403950D92D2CF0006B936 /* stats_counters.h in Headers */,
|
||||
825403970D92D2CF0006B936 /* stats_table.h in Headers */,
|
||||
825403980D92D2CF0006B936 /* string_tokenizer.h in Headers */,
|
||||
8254039A0D92D2CF0006B936 /* string_util.h in Headers */,
|
||||
7BEE52C20D9D84FD0067FF23 /* string_util_mac.h in Headers */,
|
||||
821B91690DAABD7F00F350D7 /* string16.h in Headers */,
|
||||
8254039B0D92D2CF0006B936 /* task.h in Headers */,
|
||||
8254039D0D92D2CF0006B936 /* thread.h in Headers */,
|
||||
8254039F0D92D2CF0006B936 /* thread_local_storage.h in Headers */,
|
||||
825403A10D92D2CF0006B936 /* time.h in Headers */,
|
||||
825403A30D92D2CF0006B936 /* timer.h in Headers */,
|
||||
825403A40D92D2CF0006B936 /* tuple.h in Headers */,
|
||||
825403A60D92D2CF0006B936 /* values.h in Headers */,
|
||||
825403A80D92D2CF0006B936 /* win_util.h in Headers */,
|
||||
825403AA0D92D2CF0006B936 /* wmi_util.h in Headers */,
|
||||
825403AC0D92D2CF0006B936 /* word_iterator.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
825403AD0D92D2E50006B936 /* Headers */ = {
|
||||
isa = PBXHeadersBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
825403E20D92D31D0006B936 /* bitmap_header.h in Headers */,
|
||||
825403E40D92D31D0006B936 /* bitmap_platform_device.h in Headers */,
|
||||
825403E60D92D31D0006B936 /* font_utils.h in Headers */,
|
||||
825403E80D92D31D0006B936 /* image_resizer.h in Headers */,
|
||||
825403EA0D92D31D0006B936 /* native_theme.h in Headers */,
|
||||
825403EB0D92D31D0006B936 /* platform_canvas.h in Headers */,
|
||||
825403ED0D92D31D0006B936 /* platform_device.h in Headers */,
|
||||
825403EF0D92D31D0006B936 /* png_decoder.h in Headers */,
|
||||
825403F10D92D31D0006B936 /* png_encoder.h in Headers */,
|
||||
825403F30D92D31D0006B936 /* point.h in Headers */,
|
||||
825403F60D92D31D0006B936 /* rect.h in Headers */,
|
||||
825403F80D92D31D0006B936 /* size.h in Headers */,
|
||||
825403FA0D92D31D0006B936 /* skia_utils.h in Headers */,
|
||||
825403FC0D92D31D0006B936 /* uniscribe.h in Headers */,
|
||||
825403FE0D92D31D0006B936 /* vector_canvas.h in Headers */,
|
||||
825404000D92D31D0006B936 /* vector_device.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXHeadersBuildPhase section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
825402BA0D92D0FA0006B936 /* base */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 825402BF0D92D0FB0006B936 /* Build configuration list for PBXNativeTarget "base" */;
|
||||
buildPhases = (
|
||||
825402B70D92D0FA0006B936 /* Headers */,
|
||||
825402B80D92D0FA0006B936 /* Sources */,
|
||||
825402B90D92D0FA0006B936 /* Frameworks */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = base;
|
||||
productName = base;
|
||||
productReference = 825402BB0D92D0FA0006B936 /* libbase.a */;
|
||||
productType = "com.apple.product-type.library.static";
|
||||
};
|
||||
825403B00D92D2E50006B936 /* base_gfx */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 825403B50D92D2EC0006B936 /* Build configuration list for PBXNativeTarget "base_gfx" */;
|
||||
buildPhases = (
|
||||
825403AD0D92D2E50006B936 /* Headers */,
|
||||
825403AE0D92D2E50006B936 /* Sources */,
|
||||
825403AF0D92D2E50006B936 /* Frameworks */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = base_gfx;
|
||||
productName = base_gfx;
|
||||
productReference = 825403B10D92D2E50006B936 /* libbase_gfx.a */;
|
||||
productType = "com.apple.product-type.library.static";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
825402AA0D92D0C60006B936 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
buildConfigurationList = 825402AD0D92D0C60006B936 /* Build configuration list for PBXProject "base" */;
|
||||
compatibilityVersion = "Xcode 2.4";
|
||||
hasScannedForEncodings = 0;
|
||||
mainGroup = 825402A80D92D0C60006B936;
|
||||
productRefGroup = 825402BC0D92D0FA0006B936 /* Products */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
825402BA0D92D0FA0006B936 /* base */,
|
||||
825403B00D92D2E50006B936 /* base_gfx */,
|
||||
825404020D92D3340006B936 /* All */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
825402B80D92D0FA0006B936 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
825402CE0D92D1390006B936 /* base_drag_source.cc in Sources */,
|
||||
825402D00D92D1390006B936 /* base_drop_target.cc in Sources */,
|
||||
825402D20D92D1390006B936 /* base_paths.cc in Sources */,
|
||||
825402D40D92D1390006B936 /* base_switches.cc in Sources */,
|
||||
825402E00D92D1730006B936 /* clipboard.cc in Sources */,
|
||||
825402E20D92D1730006B936 /* clipboard_util.cc in Sources */,
|
||||
825402E50D92D1850006B936 /* command_line.cc in Sources */,
|
||||
825402EF0D92D1940006B936 /* condition_variable.cc in Sources */,
|
||||
825402F60D92D1AC0006B936 /* debug_util.cc in Sources */,
|
||||
825402F80D92D1AC0006B936 /* debug_on_start.cc in Sources */,
|
||||
825403010D92D1BC0006B936 /* event_recorder.cc in Sources */,
|
||||
825403060D92D1C50006B936 /* file_util.cc in Sources */,
|
||||
8254030A0D92D1CD0006B936 /* file_version_info.cc in Sources */,
|
||||
825403140D92D1E80006B936 /* iat_patch.cc in Sources */,
|
||||
825403160D92D1E80006B936 /* icu_util.cc in Sources */,
|
||||
8254031F0D92D1F40006B936 /* image_util.cc in Sources */,
|
||||
825403210D92D1F40006B936 /* json_reader.cc in Sources */,
|
||||
825403230D92D1F40006B936 /* json_writer.cc in Sources */,
|
||||
8254032D0D92D2090006B936 /* lock.cc in Sources */,
|
||||
7BEFC29F0D99832D000829AD /* lock_impl_mac.cc in Sources */,
|
||||
8254032F0D92D2090006B936 /* logging.cc in Sources */,
|
||||
825403310D92D2090006B936 /* md5.cc in Sources */,
|
||||
825403330D92D2090006B936 /* memory_debug.cc in Sources */,
|
||||
825403370D92D2110006B936 /* message_loop.cc in Sources */,
|
||||
825403420D92D2210006B936 /* path_service.cc in Sources */,
|
||||
825403440D92D2210006B936 /* pe_image.cc in Sources */,
|
||||
825403460D92D2210006B936 /* pickle.cc in Sources */,
|
||||
82E23FCE0D9C219600F8B40A /* platform_thread.cc in Sources */,
|
||||
8254034F0D92D23C0006B936 /* prtime.cc in Sources */,
|
||||
825403540D92D24D0006B936 /* process_util.cc in Sources */,
|
||||
825403580D92D25E0006B936 /* pure_api.c in Sources */,
|
||||
825403650D92D27C0006B936 /* registry.cc in Sources */,
|
||||
825403670D92D27C0006B936 /* resource_util.cc in Sources */,
|
||||
825403690D92D27C0006B936 /* revocable_store.cc in Sources */,
|
||||
8254036D0D92D27C0006B936 /* sha2.cc in Sources */,
|
||||
825403720D92D2840006B936 /* sha512.cc in Sources */,
|
||||
825403900D92D2CF0006B936 /* shared_event.cc in Sources */,
|
||||
825403920D92D2CF0006B936 /* shared_memory.cc in Sources */,
|
||||
825403960D92D2CF0006B936 /* stats_table.cc in Sources */,
|
||||
825403990D92D2CF0006B936 /* string_util.cc in Sources */,
|
||||
7BEB834E0D9C4BE0009BA8DD /* string_util_mac.cc in Sources */,
|
||||
8254039C0D92D2CF0006B936 /* thread.cc in Sources */,
|
||||
8254039E0D92D2CF0006B936 /* thread_local_storage.cc in Sources */,
|
||||
825403A00D92D2CF0006B936 /* time.cc in Sources */,
|
||||
7BEB814A0D9B0F33009BA8DD /* time_mac.cc in Sources */,
|
||||
825403A20D92D2CF0006B936 /* timer.cc in Sources */,
|
||||
825403A50D92D2CF0006B936 /* values.cc in Sources */,
|
||||
825403A70D92D2CF0006B936 /* win_util.cc in Sources */,
|
||||
825403A90D92D2CF0006B936 /* wmi_util.cc in Sources */,
|
||||
825403AB0D92D2CF0006B936 /* word_iterator.cc in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
825403AE0D92D2E50006B936 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
825403E10D92D31D0006B936 /* bitmap_header.cc in Sources */,
|
||||
825403E30D92D31D0006B936 /* bitmap_platform_device.cc in Sources */,
|
||||
825403E50D92D31D0006B936 /* font_utils.cc in Sources */,
|
||||
825403E70D92D31D0006B936 /* image_resizer.cc in Sources */,
|
||||
825403E90D92D31D0006B936 /* native_theme.cc in Sources */,
|
||||
825403EC0D92D31D0006B936 /* platform_device.cc in Sources */,
|
||||
825403EE0D92D31D0006B936 /* png_decoder.cc in Sources */,
|
||||
825403F00D92D31D0006B936 /* png_encoder.cc in Sources */,
|
||||
825403F20D92D31D0006B936 /* point.cc in Sources */,
|
||||
825403F40D92D31D0006B936 /* rect_unittest.cc in Sources */,
|
||||
825403F50D92D31D0006B936 /* rect.cc in Sources */,
|
||||
825403F70D92D31D0006B936 /* size.cc in Sources */,
|
||||
825403F90D92D31D0006B936 /* skia_utils.cc in Sources */,
|
||||
825403FB0D92D31D0006B936 /* uniscribe.cc in Sources */,
|
||||
825403FD0D92D31D0006B936 /* vector_canvas.cc in Sources */,
|
||||
825403FF0D92D31D0006B936 /* vector_device.cc in Sources */,
|
||||
825404010D92D31D0006B936 /* platform_canvas.cc in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXTargetDependency section */
|
||||
825404060D92D33A0006B936 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = 825402BA0D92D0FA0006B936 /* base */;
|
||||
targetProxy = 825404050D92D33A0006B936 /* PBXContainerItemProxy */;
|
||||
};
|
||||
825404080D92D33C0006B936 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = 825403B00D92D2E50006B936 /* base_gfx */;
|
||||
targetProxy = 825404070D92D33C0006B936 /* PBXContainerItemProxy */;
|
||||
};
|
||||
/* End PBXTargetDependency section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
825402AB0D92D0C60006B936 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
COPY_PHASE_STRIP = NO;
|
||||
GCC_CW_ASM_SYNTAX = NO;
|
||||
GCC_ENABLE_PASCAL_STRINGS = NO;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = DEBUG;
|
||||
USE_HEADERMAP = NO;
|
||||
WARNING_CFLAGS = "-Wall";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
825402AC0D92D0C60006B936 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
COPY_PHASE_STRIP = YES;
|
||||
GCC_CW_ASM_SYNTAX = NO;
|
||||
GCC_ENABLE_PASCAL_STRINGS = NO;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = NDEBUG;
|
||||
USE_HEADERMAP = NO;
|
||||
WARNING_CFLAGS = "-Wall";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
825402BD0D92D0FB0006B936 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
COPY_PHASE_STRIP = NO;
|
||||
GCC_DYNAMIC_NO_PIC = YES;
|
||||
GCC_INLINES_ARE_PRIVATE_EXTERN = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_SYMBOLS_PRIVATE_EXTERN = YES;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
..,
|
||||
../third_party/icu38/public/common,
|
||||
../third_party/icu38/public/i18n,
|
||||
);
|
||||
PREBINDING = NO;
|
||||
PRODUCT_NAME = base;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
825402BE0D92D0FB0006B936 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
COPY_PHASE_STRIP = YES;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
GCC_DYNAMIC_NO_PIC = YES;
|
||||
GCC_INLINES_ARE_PRIVATE_EXTERN = YES;
|
||||
GCC_SYMBOLS_PRIVATE_EXTERN = YES;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
..,
|
||||
../third_party/icu38/public/common,
|
||||
../third_party/icu38/public/i18n,
|
||||
);
|
||||
PREBINDING = NO;
|
||||
PRODUCT_NAME = base;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
825403B20D92D2E50006B936 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
COPY_PHASE_STRIP = NO;
|
||||
GCC_DYNAMIC_NO_PIC = YES;
|
||||
GCC_INLINES_ARE_PRIVATE_EXTERN = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_SYMBOLS_PRIVATE_EXTERN = YES;
|
||||
PREBINDING = NO;
|
||||
PRODUCT_NAME = base_gfx;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
825403B30D92D2E50006B936 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
COPY_PHASE_STRIP = YES;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
GCC_DYNAMIC_NO_PIC = YES;
|
||||
GCC_INLINES_ARE_PRIVATE_EXTERN = YES;
|
||||
GCC_SYMBOLS_PRIVATE_EXTERN = YES;
|
||||
PREBINDING = NO;
|
||||
PRODUCT_NAME = base_gfx;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
825404030D92D3340006B936 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
COPY_PHASE_STRIP = NO;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
PRODUCT_NAME = All;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
825404040D92D3340006B936 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
COPY_PHASE_STRIP = YES;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
GCC_ENABLE_FIX_AND_CONTINUE = NO;
|
||||
PRODUCT_NAME = All;
|
||||
ZERO_LINK = NO;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
825402AD0D92D0C60006B936 /* Build configuration list for PBXProject "base" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
825402AB0D92D0C60006B936 /* Debug */,
|
||||
825402AC0D92D0C60006B936 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
825402BF0D92D0FB0006B936 /* Build configuration list for PBXNativeTarget "base" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
825402BD0D92D0FB0006B936 /* Debug */,
|
||||
825402BE0D92D0FB0006B936 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
825403B50D92D2EC0006B936 /* Build configuration list for PBXNativeTarget "base_gfx" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
825403B20D92D2E50006B936 /* Debug */,
|
||||
825403B30D92D2E50006B936 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
825404110D92D35C0006B936 /* Build configuration list for PBXAggregateTarget "All" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
825404030D92D3340006B936 /* Debug */,
|
||||
825404040D92D3340006B936 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = 825402AA0D92D0C60006B936 /* Project object */;
|
||||
}
|
88
base/base_drag_source.cc
Normal file
@ -0,0 +1,88 @@
|
||||
// Copyright 2008, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include <atlbase.h>
|
||||
|
||||
#include "base/base_drag_source.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// BaseDragSource, public:
|
||||
|
||||
BaseDragSource::BaseDragSource() : ref_count_(0) {
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// BaseDragSource, IDropSource implementation:
|
||||
|
||||
HRESULT BaseDragSource::QueryContinueDrag(BOOL escape_pressed,
|
||||
DWORD key_state) {
|
||||
if (escape_pressed) {
|
||||
OnDragSourceCancel();
|
||||
return DRAGDROP_S_CANCEL;
|
||||
}
|
||||
|
||||
if (!(key_state & MK_LBUTTON)) {
|
||||
OnDragSourceDrop();
|
||||
return DRAGDROP_S_DROP;
|
||||
}
|
||||
|
||||
OnDragSourceMove();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT BaseDragSource::GiveFeedback(DWORD effect) {
|
||||
return DRAGDROP_S_USEDEFAULTCURSORS;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// BaseDragSource, IUnknown implementation:
|
||||
|
||||
HRESULT BaseDragSource::QueryInterface(const IID& iid, void** object) {
|
||||
*object = NULL;
|
||||
if (IsEqualIID(iid, IID_IUnknown) || IsEqualIID(iid, IID_IDropSource)) {
|
||||
*object = this;
|
||||
} else {
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
ULONG BaseDragSource::AddRef() {
|
||||
return InterlockedIncrement(&ref_count_);
|
||||
}
|
||||
|
||||
ULONG BaseDragSource::Release() {
|
||||
if (InterlockedDecrement(&ref_count_) == 0) {
|
||||
ULONG copied_refcnt = ref_count_;
|
||||
delete this;
|
||||
return copied_refcnt;
|
||||
}
|
||||
return ref_count_;
|
||||
}
|
71
base/base_drag_source.h
Normal file
@ -0,0 +1,71 @@
|
||||
// Copyright 2008, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#ifndef BASE_BASE_DRAG_SOURCE_H__
|
||||
#define BASE_BASE_DRAG_SOURCE_H__
|
||||
|
||||
#include <objidl.h>
|
||||
|
||||
#include "base/basictypes.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// BaseDragSource
|
||||
//
|
||||
// A base IDropSource implementation. Handles notifications sent by an active
|
||||
// drag-drop operation as the user mouses over other drop targets on their
|
||||
// system. This object tells Windows whether or not the drag should continue,
|
||||
// and supplies the appropriate cursors.
|
||||
//
|
||||
class BaseDragSource : public IDropSource {
|
||||
public:
|
||||
BaseDragSource();
|
||||
virtual ~BaseDragSource() { }
|
||||
|
||||
// IDropSource implementation:
|
||||
HRESULT __stdcall QueryContinueDrag(BOOL escape_pressed, DWORD key_state);
|
||||
HRESULT __stdcall GiveFeedback(DWORD effect);
|
||||
|
||||
// IUnknown implementation:
|
||||
HRESULT __stdcall QueryInterface(const IID& iid, void** object);
|
||||
ULONG __stdcall AddRef();
|
||||
ULONG __stdcall Release();
|
||||
|
||||
protected:
|
||||
virtual void OnDragSourceCancel() { }
|
||||
virtual void OnDragSourceDrop() { }
|
||||
virtual void OnDragSourceMove() { }
|
||||
|
||||
private:
|
||||
LONG ref_count_;
|
||||
|
||||
DISALLOW_EVIL_CONSTRUCTORS(BaseDragSource);
|
||||
};
|
||||
|
||||
#endif // #ifndef BASE_DRAG_SOURCE_H__
|
187
base/base_drop_target.cc
Normal file
@ -0,0 +1,187 @@
|
||||
// Copyright 2008, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include <windows.h>
|
||||
#include <shlobj.h>
|
||||
|
||||
#include "base/base_drop_target.h"
|
||||
|
||||
#include "base/logging.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
IDropTargetHelper* BaseDropTarget::cached_drop_target_helper_ = NULL;
|
||||
|
||||
BaseDropTarget::BaseDropTarget(HWND hwnd)
|
||||
: suspend_(false),
|
||||
ref_count_(0),
|
||||
hwnd_(hwnd) {
|
||||
DCHECK(hwnd);
|
||||
HRESULT result = RegisterDragDrop(hwnd, this);
|
||||
}
|
||||
|
||||
BaseDropTarget::~BaseDropTarget() {
|
||||
}
|
||||
|
||||
// static
|
||||
IDropTargetHelper* BaseDropTarget::DropHelper() {
|
||||
if (!cached_drop_target_helper_) {
|
||||
CoCreateInstance(CLSID_DragDropHelper, 0, CLSCTX_INPROC_SERVER,
|
||||
IID_IDropTargetHelper,
|
||||
reinterpret_cast<void**>(&cached_drop_target_helper_));
|
||||
}
|
||||
return cached_drop_target_helper_;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// BaseDropTarget, IDropTarget implementation:
|
||||
|
||||
HRESULT BaseDropTarget::DragEnter(IDataObject* data_object,
|
||||
DWORD key_state,
|
||||
POINTL cursor_position,
|
||||
DWORD* effect) {
|
||||
// Tell the helper that we entered so it can update the drag image.
|
||||
IDropTargetHelper* drop_helper = DropHelper();
|
||||
if (drop_helper) {
|
||||
drop_helper->DragEnter(GetHWND(), data_object,
|
||||
reinterpret_cast<POINT*>(&cursor_position), *effect);
|
||||
}
|
||||
|
||||
// You can't drag and drop within the same HWND.
|
||||
if (suspend_) {
|
||||
*effect = DROPEFFECT_NONE;
|
||||
return S_OK;
|
||||
}
|
||||
current_data_object_ = data_object;
|
||||
POINT screen_pt = { cursor_position.x, cursor_position.y };
|
||||
*effect = OnDragEnter(current_data_object_, key_state, screen_pt, *effect);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT BaseDropTarget::DragOver(DWORD key_state,
|
||||
POINTL cursor_position,
|
||||
DWORD* effect) {
|
||||
// Tell the helper that we moved over it so it can update the drag image.
|
||||
IDropTargetHelper* drop_helper = DropHelper();
|
||||
if (drop_helper)
|
||||
drop_helper->DragOver(reinterpret_cast<POINT*>(&cursor_position), *effect);
|
||||
|
||||
if (suspend_) {
|
||||
*effect = DROPEFFECT_NONE;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
POINT screen_pt = { cursor_position.x, cursor_position.y };
|
||||
*effect = OnDragOver(current_data_object_, key_state, screen_pt, *effect);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT BaseDropTarget::DragLeave() {
|
||||
// Tell the helper that we moved out of it so it can update the drag image.
|
||||
IDropTargetHelper* drop_helper = DropHelper();
|
||||
if (drop_helper)
|
||||
drop_helper->DragLeave();
|
||||
|
||||
OnDragLeave(current_data_object_);
|
||||
|
||||
current_data_object_ = NULL;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT BaseDropTarget::Drop(IDataObject* data_object,
|
||||
DWORD key_state,
|
||||
POINTL cursor_position,
|
||||
DWORD* effect) {
|
||||
// Tell the helper that we dropped onto it so it can update the drag image.
|
||||
IDropTargetHelper* drop_helper = DropHelper();
|
||||
if (drop_helper) {
|
||||
drop_helper->Drop(current_data_object_,
|
||||
reinterpret_cast<POINT*>(&cursor_position), *effect);
|
||||
}
|
||||
|
||||
if (suspend_) {
|
||||
*effect = DROPEFFECT_NONE;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
POINT screen_pt = { cursor_position.x, cursor_position.y };
|
||||
*effect = OnDrop(current_data_object_, key_state, screen_pt, *effect);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// BaseDropTarget, IUnknown implementation:
|
||||
|
||||
HRESULT BaseDropTarget::QueryInterface(const IID& iid, void** object) {
|
||||
*object = NULL;
|
||||
if (IsEqualIID(iid, IID_IUnknown) || IsEqualIID(iid, IID_IDropTarget)) {
|
||||
*object = this;
|
||||
} else {
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
ULONG BaseDropTarget::AddRef() {
|
||||
return InterlockedIncrement(&ref_count_);
|
||||
}
|
||||
|
||||
ULONG BaseDropTarget::Release() {
|
||||
if (InterlockedDecrement(&ref_count_) == 0) {
|
||||
ULONG copied_refcnt = ref_count_;
|
||||
delete this;
|
||||
return copied_refcnt;
|
||||
}
|
||||
return ref_count_;
|
||||
}
|
||||
|
||||
DWORD BaseDropTarget::OnDragEnter(IDataObject* data_object,
|
||||
DWORD key_state,
|
||||
POINT cursor_position,
|
||||
DWORD effect) {
|
||||
return DROPEFFECT_NONE;
|
||||
}
|
||||
|
||||
DWORD BaseDropTarget::OnDragOver(IDataObject* data_object,
|
||||
DWORD key_state,
|
||||
POINT cursor_position,
|
||||
DWORD effect) {
|
||||
return DROPEFFECT_NONE;
|
||||
}
|
||||
|
||||
void BaseDropTarget::OnDragLeave(IDataObject* data_object) {
|
||||
}
|
||||
|
||||
DWORD BaseDropTarget::OnDrop(IDataObject* data_object,
|
||||
DWORD key_state,
|
||||
POINT cursor_position,
|
||||
DWORD effect) {
|
||||
return DROPEFFECT_NONE;
|
||||
}
|
142
base/base_drop_target.h
Normal file
@ -0,0 +1,142 @@
|
||||
// Copyright 2008, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#ifndef BASE_BASE_DROP_TARGET_H__
|
||||
#define BASE_BASE_DROP_TARGET_H__
|
||||
|
||||
#include <atlbase.h>
|
||||
#include <objidl.h>
|
||||
#include <shobjidl.h>
|
||||
|
||||
#include "base/basictypes.h"
|
||||
|
||||
// A DropTarget implementation that takes care of the nitty gritty
|
||||
// of dnd. While this class is concrete, subclasses will most likely
|
||||
// want to override various OnXXX methods.
|
||||
//
|
||||
// Because BaseDropTarget is ref counted you shouldn't delete it directly,
|
||||
// rather wrap it in a scoped_refptr. Be sure and invoke RevokeDragDrop(m_hWnd)
|
||||
// before the HWND is deleted too.
|
||||
class BaseDropTarget : public IDropTarget {
|
||||
public:
|
||||
// Create a new BaseDropTarget associating it with the given HWND.
|
||||
explicit BaseDropTarget(HWND hwnd);
|
||||
virtual ~BaseDropTarget();
|
||||
|
||||
// When suspend is set to |true|, the drop target does not receive drops from
|
||||
// drags initiated within the owning HWND.
|
||||
// TODO(beng): (http://b/1085385) figure out how we will handle legitimate
|
||||
// drag-drop operations within the same HWND, such as dragging
|
||||
// selected text to an edit field.
|
||||
void set_suspend(bool suspend) { suspend_ = suspend; }
|
||||
|
||||
// IDropTarget implementation:
|
||||
HRESULT __stdcall DragEnter(IDataObject* data_object,
|
||||
DWORD key_state,
|
||||
POINTL cursor_position,
|
||||
DWORD* effect);
|
||||
HRESULT __stdcall DragOver(DWORD key_state,
|
||||
POINTL cursor_position,
|
||||
DWORD* effect);
|
||||
HRESULT __stdcall DragLeave();
|
||||
HRESULT __stdcall Drop(IDataObject* data_object,
|
||||
DWORD key_state,
|
||||
POINTL cursor_position,
|
||||
DWORD* effect);
|
||||
|
||||
// IUnknown implementation:
|
||||
HRESULT __stdcall QueryInterface(const IID& iid, void** object);
|
||||
ULONG __stdcall AddRef();
|
||||
ULONG __stdcall Release();
|
||||
|
||||
protected:
|
||||
// Returns the hosting HWND.
|
||||
HWND GetHWND() { return hwnd_; }
|
||||
|
||||
// Invoked when the cursor first moves over the hwnd during a dnd session.
|
||||
// This should return a bitmask of the supported drop operations:
|
||||
// DROPEFFECT_NONE, DROPEFFECT_COPY, DROPEFFECT_LINK and/or
|
||||
// DROPEFFECT_MOVE.
|
||||
virtual DWORD OnDragEnter(IDataObject* data_object,
|
||||
DWORD key_state,
|
||||
POINT cursor_position,
|
||||
DWORD effect);
|
||||
|
||||
// Invoked when the cursor moves over the window during a dnd session.
|
||||
// This should return a bitmask of the supported drop operations:
|
||||
// DROPEFFECT_NONE, DROPEFFECT_COPY, DROPEFFECT_LINK and/or
|
||||
// DROPEFFECT_MOVE.
|
||||
virtual DWORD OnDragOver(IDataObject* data_object,
|
||||
DWORD key_state,
|
||||
POINT cursor_position,
|
||||
DWORD effect);
|
||||
|
||||
// Invoked when the cursor moves outside the bounds of the hwnd during a
|
||||
// dnd session.
|
||||
virtual void OnDragLeave(IDataObject* data_object);
|
||||
|
||||
// Invoked when the drop ends on the window. This should return the operation
|
||||
// that was taken.
|
||||
virtual DWORD OnDrop(IDataObject* data_object,
|
||||
DWORD key_state,
|
||||
POINT cursor_position,
|
||||
DWORD effect);
|
||||
|
||||
private:
|
||||
// Returns the cached drop helper, creating one if necessary. The returned
|
||||
// object is not addrefed. May return NULL if the object couldn't be created.
|
||||
static IDropTargetHelper* DropHelper();
|
||||
|
||||
// The data object currently being dragged over this drop target.
|
||||
CComPtr<IDataObject> current_data_object_;
|
||||
|
||||
// A helper object that is used to provide drag image support while the mouse
|
||||
// is dragging over the content area.
|
||||
//
|
||||
// DO NOT ACCESS DIRECTLY! Use DropHelper() instead, which will lazily create
|
||||
// this if it doesn't exist yet. This object can take tens of milliseconds to
|
||||
// create, and we don't want to block any window opening for this, especially
|
||||
// since often, DnD will never be used. Instead, we force this penalty to the
|
||||
// first time it is actually used.
|
||||
static IDropTargetHelper* cached_drop_target_helper_;
|
||||
|
||||
// The HWND of the source. This HWND is used to determine coordinates for
|
||||
// mouse events that are sent to the renderer notifying various drag states.
|
||||
HWND hwnd_;
|
||||
|
||||
// Whether or not we are currently processing drag notifications for drags
|
||||
// initiated in this window.
|
||||
bool suspend_;
|
||||
|
||||
LONG ref_count_;
|
||||
|
||||
DISALLOW_EVIL_CONSTRUCTORS(BaseDropTarget);
|
||||
};
|
||||
|
||||
#endif // BASE_BASE_DROP_TARGET_H__
|
151
base/base_paths.cc
Normal file
@ -0,0 +1,151 @@
|
||||
// Copyright 2008, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include "base/base_paths.h"
|
||||
|
||||
#include <shlobj.h>
|
||||
|
||||
#include "base/file_util.h"
|
||||
#include "base/path_service.h"
|
||||
|
||||
// This is here for the sole purpose of looking up the corresponding HMODULE.
|
||||
static int handle_lookup = 0;
|
||||
|
||||
namespace base {
|
||||
|
||||
bool PathProvider(int key, std::wstring* result) {
|
||||
// NOTE: DIR_CURRENT is a special cased in PathService::Get
|
||||
|
||||
// We need to go compute the value. It would be nice to support paths with
|
||||
// names longer than MAX_PATH, but the system functions don't seem to be
|
||||
// designed for it either, with the exception of GetTempPath (but other
|
||||
// things will surely break if the temp path is too long, so we don't bother
|
||||
// handling it.
|
||||
wchar_t system_buffer[MAX_PATH];
|
||||
system_buffer[0] = 0;
|
||||
|
||||
std::wstring cur;
|
||||
switch (key) {
|
||||
case base::FILE_EXE:
|
||||
GetModuleFileName(NULL, system_buffer, MAX_PATH);
|
||||
cur = system_buffer;
|
||||
break;
|
||||
case base::FILE_MODULE: {
|
||||
// the resource containing module is assumed to be the one that
|
||||
// this code lives in, whether that's a dll or exe
|
||||
MEMORY_BASIC_INFORMATION info = { 0 };
|
||||
VirtualQuery(reinterpret_cast<void*>(&handle_lookup),
|
||||
&info, sizeof(info));
|
||||
// Module handles are just the allocation base address of the module.
|
||||
HMODULE this_module = reinterpret_cast<HMODULE>(info.AllocationBase);
|
||||
GetModuleFileName(this_module, system_buffer, MAX_PATH);
|
||||
cur = system_buffer;
|
||||
break;
|
||||
}
|
||||
case base::DIR_EXE:
|
||||
PathProvider(base::FILE_EXE, &cur);
|
||||
file_util::TrimFilename(&cur);
|
||||
break;
|
||||
case base::DIR_MODULE:
|
||||
PathProvider(base::FILE_MODULE, &cur);
|
||||
file_util::TrimFilename(&cur);
|
||||
break;
|
||||
case base::DIR_TEMP:
|
||||
if (!file_util::GetTempDir(&cur))
|
||||
return false;
|
||||
break;
|
||||
case base::DIR_WINDOWS:
|
||||
GetWindowsDirectory(system_buffer, MAX_PATH);
|
||||
cur = system_buffer;
|
||||
break;
|
||||
case base::DIR_SYSTEM:
|
||||
GetSystemDirectory(system_buffer, MAX_PATH);
|
||||
cur = system_buffer;
|
||||
break;
|
||||
case base::DIR_PROGRAM_FILES:
|
||||
if (FAILED(SHGetFolderPath(NULL, CSIDL_PROGRAM_FILES, NULL,
|
||||
SHGFP_TYPE_CURRENT, system_buffer)))
|
||||
return false;
|
||||
cur = system_buffer;
|
||||
break;
|
||||
case base::DIR_SOURCE_ROOT:
|
||||
// By default, unit tests execute two levels deep from the source root.
|
||||
// For example: chrome/{Debug|Release}/ui_tests.exe
|
||||
PathProvider(base::DIR_EXE, &cur);
|
||||
file_util::UpOneDirectory(&cur);
|
||||
file_util::UpOneDirectory(&cur);
|
||||
break;
|
||||
case base::DIR_APP_DATA:
|
||||
if (FAILED(SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT,
|
||||
system_buffer)))
|
||||
return false;
|
||||
cur = system_buffer;
|
||||
break;
|
||||
case base::DIR_LOCAL_APP_DATA_LOW:
|
||||
// TODO(nsylvain): We should use SHGetKnownFolderPath instead. Bug 1281128
|
||||
if (FAILED(SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT,
|
||||
system_buffer)))
|
||||
return false;
|
||||
cur = system_buffer;
|
||||
file_util::UpOneDirectory(&cur);
|
||||
file_util::AppendToPath(&cur, L"LocalLow");
|
||||
break;
|
||||
case base::DIR_LOCAL_APP_DATA:
|
||||
if (FAILED(SHGetFolderPath(NULL, CSIDL_LOCAL_APPDATA, NULL,
|
||||
SHGFP_TYPE_CURRENT, system_buffer)))
|
||||
return false;
|
||||
cur = system_buffer;
|
||||
break;
|
||||
case base::DIR_IE_INTERNET_CACHE:
|
||||
if (FAILED(SHGetFolderPath(NULL, CSIDL_INTERNET_CACHE, NULL,
|
||||
SHGFP_TYPE_CURRENT, system_buffer)))
|
||||
return false;
|
||||
cur = system_buffer;
|
||||
break;
|
||||
case base::DIR_COMMON_START_MENU:
|
||||
if (FAILED(SHGetFolderPath(NULL, CSIDL_COMMON_PROGRAMS, NULL,
|
||||
SHGFP_TYPE_CURRENT, system_buffer)))
|
||||
return false;
|
||||
cur = system_buffer;
|
||||
break;
|
||||
case base::DIR_START_MENU:
|
||||
if (FAILED(SHGetFolderPath(NULL, CSIDL_PROGRAMS, NULL,
|
||||
SHGFP_TYPE_CURRENT, system_buffer)))
|
||||
return false;
|
||||
cur = system_buffer;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
result->swap(cur);
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace base
|
70
base/base_paths.h
Normal file
@ -0,0 +1,70 @@
|
||||
// Copyright 2008, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#ifndef BASE_BASE_PATHS_H__
|
||||
#define BASE_BASE_PATHS_H__
|
||||
|
||||
// This file declares path keys for the base module. These can be used with
|
||||
// the PathService to access various special directories and files.
|
||||
|
||||
namespace base {
|
||||
|
||||
enum {
|
||||
PATH_START = 0,
|
||||
|
||||
DIR_CURRENT, // current directory
|
||||
DIR_EXE, // directory containing FILE_EXE
|
||||
DIR_MODULE, // directory containing FILE_MODULE
|
||||
FILE_EXE, // path and filename of the current executable
|
||||
FILE_MODULE, // path and filename of the module containing the code for the
|
||||
// PathService (which could differ from FILE_EXE if the
|
||||
// PathService were compiled into a DLL, for example)
|
||||
DIR_TEMP, // temporary directory
|
||||
DIR_WINDOWS, // Windows directory, usually "c:\windows"
|
||||
DIR_SYSTEM, // Usually c:\windows\system32"
|
||||
DIR_PROGRAM_FILES, // Usually c:\program files
|
||||
|
||||
DIR_SOURCE_ROOT, // Returns the root of the source tree. This key is useful
|
||||
// for tests that need to locate various resources. It
|
||||
// should not be used outside of test code.
|
||||
DIR_APP_DATA, // Application Data directory under the user profile.
|
||||
DIR_LOCAL_APP_DATA_LOW, // Local AppData directory for low integrity level.
|
||||
DIR_LOCAL_APP_DATA, // "Local Settings\Application Data" directory under the
|
||||
// user profile.
|
||||
DIR_IE_INTERNET_CACHE, // Temporary Internet Files directory.
|
||||
DIR_COMMON_START_MENU, // Usually "C:\Documents and Settings\All Users\
|
||||
// Start Menu\Programs"
|
||||
DIR_START_MENU, // Usually "C:\Documents and Settings\<user>\
|
||||
// Start Menu\Programs"
|
||||
PATH_END
|
||||
};
|
||||
|
||||
} // namespace base
|
||||
|
||||
#endif // BASE_BASE_PATHS_H__
|
58
base/base_switches.cc
Normal file
@ -0,0 +1,58 @@
|
||||
// Copyright 2008, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include "base/base_switches.h"
|
||||
|
||||
namespace switches {
|
||||
|
||||
// If the program includes chrome/common/debug_on_start.h, the process will
|
||||
// start the JIT system-registered debugger on itself and will wait for 60
|
||||
// seconds for the debugger to attach to itself. Then a break point will be hit.
|
||||
const wchar_t kDebugOnStart[] = L"debug-on-start";
|
||||
|
||||
// Will wait for 60 seconds for a debugger to come to attach to the process.
|
||||
const wchar_t kWaitForDebugger[] = L"wait-for-debugger";
|
||||
|
||||
// Suppresses all error dialogs when present.
|
||||
const wchar_t kNoErrorDialogs[] = L"noerrdialogs";
|
||||
|
||||
// Disables the crash reporting.
|
||||
const wchar_t kDisableBreakpad[] = L"disable-breakpad";
|
||||
|
||||
// Generates full memory crash dump.
|
||||
const wchar_t kFullMemoryCrashReport[] = L"full-memory-crash-report";
|
||||
|
||||
// The value of this switch determines whether the process is started as a
|
||||
// renderer or plugin host. If it's empty, it's the browser.
|
||||
const wchar_t kProcessType[] = L"type";
|
||||
|
||||
// Enable DCHECKs in release mode.
|
||||
const wchar_t kEnableDCHECK[] = L"enable-dcheck";
|
||||
|
||||
} // namespace switches
|
47
base/base_switches.h
Normal file
@ -0,0 +1,47 @@
|
||||
// Copyright 2008, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Defines all the "base" command-line switches.
|
||||
|
||||
#ifndef BASE_SWITCHES_H__
|
||||
#define BASE_SWITCHES_H__
|
||||
|
||||
namespace switches {
|
||||
|
||||
extern const wchar_t kDebugOnStart[];
|
||||
extern const wchar_t kWaitForDebugger[];
|
||||
extern const wchar_t kDisableBreakpad[];
|
||||
extern const wchar_t kFullMemoryCrashReport[];
|
||||
extern const wchar_t kNoErrorDialogs[];
|
||||
extern const wchar_t kProcessType[];
|
||||
extern const wchar_t kEnableDCHECK[];
|
||||
|
||||
} // namespace switches
|
||||
|
||||
#endif // CHROME_COMMON_CHROME_SWITCHES_H__
|
403
base/basictypes.h
Normal file
@ -0,0 +1,403 @@
|
||||
// Copyright 2008, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
// Copied from base/basictypes.h with some modifications
|
||||
|
||||
#ifndef BASE_BASICTYPES_H__
|
||||
#define BASE_BASICTYPES_H__
|
||||
|
||||
#include <assert.h> // for use with down_cast<>
|
||||
#include <limits.h> // So we can set the bounds of our types
|
||||
#include <stddef.h> // For size_t
|
||||
#include <string.h> // for memcpy
|
||||
|
||||
#include "base/port.h" // Types that only need exist on certain systems
|
||||
|
||||
typedef signed char schar;
|
||||
typedef signed char int8;
|
||||
typedef short int16;
|
||||
// TODO(mbelshe) Remove these type guards. These are
|
||||
// temporary to avoid conflicts with npapi.h.
|
||||
#ifndef _INT32
|
||||
#define _INT32
|
||||
typedef int int32;
|
||||
#endif
|
||||
typedef long long int64;
|
||||
|
||||
// NOTE: unsigned types are DANGEROUS in loops and other arithmetical
|
||||
// places. Use the signed types unless your variable represents a bit
|
||||
// pattern (eg a hash value) or you really need the extra bit. Do NOT
|
||||
// use 'unsigned' to express "this value should always be positive";
|
||||
// use assertions for this.
|
||||
|
||||
typedef unsigned char uint8;
|
||||
typedef unsigned short uint16;
|
||||
// TODO(mbelshe) Remove these type guards. These are
|
||||
// temporary to avoid conflicts with npapi.h.
|
||||
#ifndef _UINT32
|
||||
#define _UINT32
|
||||
typedef unsigned int uint32;
|
||||
#endif
|
||||
typedef unsigned long long uint64;
|
||||
|
||||
// A type to represent a Unicode code-point value. As of Unicode 4.0,
|
||||
// such values require up to 21 bits.
|
||||
// (For type-checking on pointers, make this explicitly signed,
|
||||
// and it should always be the signed version of whatever int32 is.)
|
||||
typedef signed int char32;
|
||||
|
||||
const uint8 kuint8max = UCHAR_MAX;
|
||||
const uint16 kuint16max = USHRT_MAX;
|
||||
const uint32 kuint32max = UINT_MAX;
|
||||
const uint64 kuint64max = ULLONG_MAX;
|
||||
const int8 kint8min = SCHAR_MIN;
|
||||
const int8 kint8max = SCHAR_MAX;
|
||||
const int16 kint16min = SHRT_MIN;
|
||||
const int16 kint16max = SHRT_MAX;
|
||||
const int32 kint32min = INT_MIN;
|
||||
const int32 kint32max = INT_MAX;
|
||||
const int64 kint64min = LLONG_MIN;
|
||||
const int64 kint64max = LLONG_MAX;
|
||||
|
||||
// id for odp categories
|
||||
typedef uint32 CatId;
|
||||
const CatId kIllegalCatId = static_cast<CatId>(0);
|
||||
|
||||
typedef uint32 TermId;
|
||||
const TermId kIllegalTermId = static_cast<TermId>(0);
|
||||
|
||||
typedef uint32 HostId;
|
||||
const HostId kIllegalHostId = static_cast<HostId>(0);
|
||||
|
||||
typedef uint32 DomainId;
|
||||
const DomainId kIllegalDomainId = static_cast<DomainId>(0);
|
||||
|
||||
// A macro to disallow the copy constructor and operator= functions
|
||||
// This should be used in the private: declarations for a class
|
||||
#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
|
||||
TypeName(const TypeName&); \
|
||||
void operator=(const TypeName&)
|
||||
|
||||
// An older, deprecated, politically incorrect name for the above.
|
||||
#define DISALLOW_EVIL_CONSTRUCTORS(TypeName) DISALLOW_COPY_AND_ASSIGN(TypeName)
|
||||
|
||||
// A macro to disallow all the implicit constructors, namely the
|
||||
// default constructor, copy constructor and operator= functions.
|
||||
//
|
||||
// This should be used in the private: declarations for a class
|
||||
// that wants to prevent anyone from instantiating it. This is
|
||||
// especially useful for classes containing only static methods.
|
||||
#define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \
|
||||
TypeName(); \
|
||||
DISALLOW_COPY_AND_ASSIGN(TypeName)
|
||||
|
||||
// The arraysize(arr) macro returns the # of elements in an array arr.
|
||||
// The expression is a compile-time constant, and therefore can be
|
||||
// used in defining new arrays, for example. If you use arraysize on
|
||||
// a pointer by mistake, you will get a compile-time error.
|
||||
//
|
||||
// One caveat is that arraysize() doesn't accept any array of an
|
||||
// anonymous type or a type defined inside a function. In these rare
|
||||
// cases, you have to use the unsafe ARRAYSIZE() macro below. This is
|
||||
// due to a limitation in C++'s template system. The limitation might
|
||||
// eventually be removed, but it hasn't happened yet.
|
||||
|
||||
// This template function declaration is used in defining arraysize.
|
||||
// Note that the function doesn't need an implementation, as we only
|
||||
// use its type.
|
||||
template <typename T, size_t N>
|
||||
char (&ArraySizeHelper(T (&array)[N]))[N];
|
||||
|
||||
// That gcc wants both of these prototypes seems mysterious. VC, for
|
||||
// its part, can't decide which to use (another mystery). Matching of
|
||||
// template overloads: the final frontier.
|
||||
#ifndef _MSC_VER
|
||||
template <typename T, size_t N>
|
||||
char (&ArraySizeHelper(const T (&array)[N]))[N];
|
||||
#endif
|
||||
|
||||
#define arraysize(array) (sizeof(ArraySizeHelper(array)))
|
||||
|
||||
// ARRAYSIZE performs essentially the same calculation as arraysize,
|
||||
// but can be used on anonymous types or types defined inside
|
||||
// functions. It's less safe than arraysize as it accepts some
|
||||
// (although not all) pointers. Therefore, you should use arraysize
|
||||
// whenever possible.
|
||||
//
|
||||
// The expression ARRAYSIZE(a) is a compile-time constant of type
|
||||
// size_t.
|
||||
//
|
||||
// ARRAYSIZE catches a few type errors. If you see a compiler error
|
||||
//
|
||||
// "warning: division by zero in ..."
|
||||
//
|
||||
// when using ARRAYSIZE, you are (wrongfully) giving it a pointer.
|
||||
// You should only use ARRAYSIZE on statically allocated arrays.
|
||||
//
|
||||
// The following comments are on the implementation details, and can
|
||||
// be ignored by the users.
|
||||
//
|
||||
// ARRAYSIZE(arr) works by inspecting sizeof(arr) (the # of bytes in
|
||||
// the array) and sizeof(*(arr)) (the # of bytes in one array
|
||||
// element). If the former is divisible by the latter, perhaps arr is
|
||||
// indeed an array, in which case the division result is the # of
|
||||
// elements in the array. Otherwise, arr cannot possibly be an array,
|
||||
// and we generate a compiler error to prevent the code from
|
||||
// compiling.
|
||||
//
|
||||
// Since the size of bool is implementation-defined, we need to cast
|
||||
// !(sizeof(a) & sizeof(*(a))) to size_t in order to ensure the final
|
||||
// result has type size_t.
|
||||
//
|
||||
// This macro is not perfect as it wrongfully accepts certain
|
||||
// pointers, namely where the pointer size is divisible by the pointee
|
||||
// size. Since all our code has to go through a 32-bit compiler,
|
||||
// where a pointer is 4 bytes, this means all pointers to a type whose
|
||||
// size is 3 or greater than 4 will be (righteously) rejected.
|
||||
|
||||
#define ARRAYSIZE_UNSAFE(a) \
|
||||
((sizeof(a) / sizeof(*(a))) / \
|
||||
static_cast<size_t>(!(sizeof(a) % sizeof(*(a)))))
|
||||
|
||||
|
||||
// Use implicit_cast as a safe version of static_cast or const_cast
|
||||
// for upcasting in the type hierarchy (i.e. casting a pointer to Foo
|
||||
// to a pointer to SuperclassOfFoo or casting a pointer to Foo to
|
||||
// a const pointer to Foo).
|
||||
// When you use implicit_cast, the compiler checks that the cast is safe.
|
||||
// Such explicit implicit_casts are necessary in surprisingly many
|
||||
// situations where C++ demands an exact type match instead of an
|
||||
// argument type convertable to a target type.
|
||||
//
|
||||
// The From type can be inferred, so the preferred syntax for using
|
||||
// implicit_cast is the same as for static_cast etc.:
|
||||
//
|
||||
// implicit_cast<ToType>(expr)
|
||||
//
|
||||
// implicit_cast would have been part of the C++ standard library,
|
||||
// but the proposal was submitted too late. It will probably make
|
||||
// its way into the language in the future.
|
||||
template<typename To, typename From>
|
||||
inline To implicit_cast(From const &f) {
|
||||
return f;
|
||||
}
|
||||
|
||||
|
||||
// When you upcast (that is, cast a pointer from type Foo to type
|
||||
// SuperclassOfFoo), it's fine to use implicit_cast<>, since upcasts
|
||||
// always succeed. When you downcast (that is, cast a pointer from
|
||||
// type Foo to type SubclassOfFoo), static_cast<> isn't safe, because
|
||||
// how do you know the pointer is really of type SubclassOfFoo? It
|
||||
// could be a bare Foo, or of type DifferentSubclassOfFoo. Thus,
|
||||
// when you downcast, you should use this macro. In debug mode, we
|
||||
// use dynamic_cast<> to double-check the downcast is legal (we die
|
||||
// if it's not). In normal mode, we do the efficient static_cast<>
|
||||
// instead. Thus, it's important to test in debug mode to make sure
|
||||
// the cast is legal!
|
||||
// This is the only place in the code we should use dynamic_cast<>.
|
||||
// In particular, you SHOULDN'T be using dynamic_cast<> in order to
|
||||
// do RTTI (eg code like this:
|
||||
// if (dynamic_cast<Subclass1>(foo)) HandleASubclass1Object(foo);
|
||||
// if (dynamic_cast<Subclass2>(foo)) HandleASubclass2Object(foo);
|
||||
// You should design the code some other way not to need this.
|
||||
|
||||
template<typename To, typename From> // use like this: down_cast<T*>(foo);
|
||||
inline To down_cast(From* f) { // so we only accept pointers
|
||||
// Ensures that To is a sub-type of From *. This test is here only
|
||||
// for compile-time type checking, and has no overhead in an
|
||||
// optimized build at run-time, as it will be optimized away
|
||||
// completely.
|
||||
if (false) {
|
||||
implicit_cast<From*, To>(0);
|
||||
}
|
||||
|
||||
assert(f == NULL || dynamic_cast<To>(f) != NULL); // RTTI: debug mode only!
|
||||
return static_cast<To>(f);
|
||||
}
|
||||
|
||||
// The COMPILE_ASSERT macro can be used to verify that a compile time
|
||||
// expression is true. For example, you could use it to verify the
|
||||
// size of a static array:
|
||||
//
|
||||
// COMPILE_ASSERT(ARRAYSIZE(content_type_names) == CONTENT_NUM_TYPES,
|
||||
// content_type_names_incorrect_size);
|
||||
//
|
||||
// or to make sure a struct is smaller than a certain size:
|
||||
//
|
||||
// COMPILE_ASSERT(sizeof(foo) < 128, foo_too_large);
|
||||
//
|
||||
// The second argument to the macro is the name of the variable. If
|
||||
// the expression is false, most compilers will issue a warning/error
|
||||
// containing the name of the variable.
|
||||
|
||||
template <bool>
|
||||
struct CompileAssert {
|
||||
};
|
||||
|
||||
#undef COMPILE_ASSERT
|
||||
#define COMPILE_ASSERT(expr, msg) \
|
||||
typedef CompileAssert<(bool(expr))> msg[bool(expr) ? 1 : -1]
|
||||
|
||||
// Implementation details of COMPILE_ASSERT:
|
||||
//
|
||||
// - COMPILE_ASSERT works by defining an array type that has -1
|
||||
// elements (and thus is invalid) when the expression is false.
|
||||
//
|
||||
// - The simpler definition
|
||||
//
|
||||
// #define COMPILE_ASSERT(expr, msg) typedef char msg[(expr) ? 1 : -1]
|
||||
//
|
||||
// does not work, as gcc supports variable-length arrays whose sizes
|
||||
// are determined at run-time (this is gcc's extension and not part
|
||||
// of the C++ standard). As a result, gcc fails to reject the
|
||||
// following code with the simple definition:
|
||||
//
|
||||
// int foo;
|
||||
// COMPILE_ASSERT(foo, msg); // not supposed to compile as foo is
|
||||
// // not a compile-time constant.
|
||||
//
|
||||
// - By using the type CompileAssert<(bool(expr))>, we ensures that
|
||||
// expr is a compile-time constant. (Template arguments must be
|
||||
// determined at compile-time.)
|
||||
//
|
||||
// - The outter parentheses in CompileAssert<(bool(expr))> are necessary
|
||||
// to work around a bug in gcc 3.4.4 and 4.0.1. If we had written
|
||||
//
|
||||
// CompileAssert<bool(expr)>
|
||||
//
|
||||
// instead, these compilers will refuse to compile
|
||||
//
|
||||
// COMPILE_ASSERT(5 > 0, some_message);
|
||||
//
|
||||
// (They seem to think the ">" in "5 > 0" marks the end of the
|
||||
// template argument list.)
|
||||
//
|
||||
// - The array size is (bool(expr) ? 1 : -1), instead of simply
|
||||
//
|
||||
// ((expr) ? 1 : -1).
|
||||
//
|
||||
// This is to avoid running into a bug in MS VC 7.1, which
|
||||
// causes ((0.0) ? 1 : -1) to incorrectly evaluate to 1.
|
||||
|
||||
|
||||
// MetatagId refers to metatag-id that we assign to
|
||||
// each metatag <name, value> pair..
|
||||
typedef uint32 MetatagId;
|
||||
|
||||
// Argument type used in interfaces that can optionally take ownership
|
||||
// of a passed in argument. If TAKE_OWNERSHIP is passed, the called
|
||||
// object takes ownership of the argument. Otherwise it does not.
|
||||
enum Ownership {
|
||||
DO_NOT_TAKE_OWNERSHIP,
|
||||
TAKE_OWNERSHIP
|
||||
};
|
||||
|
||||
// Use these as the mlock_bytes parameter to MLock and MLockGeneral
|
||||
enum { MLOCK_ALL = -1, MLOCK_NONE = 0 };
|
||||
|
||||
// Helper routine to avoid buggy code like the following:
|
||||
// if (pos + N < end) ...
|
||||
// If pos is large enough, "pos + N" may overflow. For example,
|
||||
// pos==0xfffff000 and N==1MB.
|
||||
//
|
||||
// This often happens on Nacona's in 32-bit mode, because the
|
||||
// main thread's stack is put very close to address 0xffffffff.
|
||||
//
|
||||
// PointerRangeSize(a,b) returns the size of the range [a,b-1]
|
||||
inline size_t PointerRangeSize(const char* start, const char* end) {
|
||||
assert(start <= end);
|
||||
return end - start;
|
||||
}
|
||||
|
||||
// bit_cast<Dest,Source> is a template function that implements the
|
||||
// equivalent of "*reinterpret_cast<Dest*>(&source)". We need this in
|
||||
// very low-level functions like the protobuf library and fast math
|
||||
// support.
|
||||
//
|
||||
// float f = 3.14159265358979;
|
||||
// int i = bit_cast<int32>(f);
|
||||
// // i = 0x40490fdb
|
||||
//
|
||||
// The classical address-casting method is:
|
||||
//
|
||||
// // WRONG
|
||||
// float f = 3.14159265358979; // WRONG
|
||||
// int i = * reinterpret_cast<int*>(&f); // WRONG
|
||||
//
|
||||
// The address-casting method actually produces undefined behavior
|
||||
// according to ISO C++ specification section 3.10 -15 -. Roughly, this
|
||||
// section says: if an object in memory has one type, and a program
|
||||
// accesses it with a different type, then the result is undefined
|
||||
// behavior for most values of "different type".
|
||||
//
|
||||
// This is true for any cast syntax, either *(int*)&f or
|
||||
// *reinterpret_cast<int*>(&f). And it is particularly true for
|
||||
// conversions betweeen integral lvalues and floating-point lvalues.
|
||||
//
|
||||
// The purpose of 3.10 -15- is to allow optimizing compilers to assume
|
||||
// that expressions with different types refer to different memory. gcc
|
||||
// 4.0.1 has an optimizer that takes advantage of this. So a
|
||||
// non-conforming program quietly produces wildly incorrect output.
|
||||
//
|
||||
// The problem is not the use of reinterpret_cast. The problem is type
|
||||
// punning: holding an object in memory of one type and reading its bits
|
||||
// back using a different type.
|
||||
//
|
||||
// The C++ standard is more subtle and complex than this, but that
|
||||
// is the basic idea.
|
||||
//
|
||||
// Anyways ...
|
||||
//
|
||||
// bit_cast<> calls memcpy() which is blessed by the standard,
|
||||
// especially by the example in section 3.9 . Also, of course,
|
||||
// bit_cast<> wraps up the nasty logic in one place.
|
||||
//
|
||||
// Fortunately memcpy() is very fast. In optimized mode, with a
|
||||
// constant size, gcc 2.95.3, gcc 4.0.1, and msvc 7.1 produce inline
|
||||
// code with the minimal amount of data movement. On a 32-bit system,
|
||||
// memcpy(d,s,4) compiles to one load and one store, and memcpy(d,s,8)
|
||||
// compiles to two loads and two stores.
|
||||
//
|
||||
// I tested this code with gcc 2.95.3, gcc 4.0.1, icc 8.1, and msvc 7.1.
|
||||
//
|
||||
// WARNING: if Dest or Source is a non-POD type, the result of the memcpy
|
||||
// is likely to surprise you.
|
||||
|
||||
template <class Dest, class Source>
|
||||
inline Dest bit_cast(const Source& source) {
|
||||
// Compile time assertion: sizeof(Dest) == sizeof(Source)
|
||||
// A compile error here means your Dest and Source have different sizes.
|
||||
typedef char VerifySizesAreEqual [sizeof(Dest) == sizeof(Source) ? 1 : -1];
|
||||
|
||||
Dest dest;
|
||||
memcpy(&dest, &source, sizeof(dest));
|
||||
return dest;
|
||||
}
|
||||
|
||||
|
||||
#endif // BASE_BASICTYPES_H__
|
719
base/build/base.vcproj
Normal file
@ -0,0 +1,719 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="8.00"
|
||||
Name="base"
|
||||
ProjectGUID="{1832A374-8A74-4F9E-B536-69A699B3E165}"
|
||||
RootNamespace="base"
|
||||
Keyword="Win32Proj"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
ConfigurationType="4"
|
||||
InheritedPropertySheets="$(SolutionDir)..\build\debug.vsprops;.\base.vsprops"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
ConfigurationType="4"
|
||||
InheritedPropertySheets="$(SolutionDir)..\build\release.vsprops;.\base.vsprops"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<File
|
||||
RelativePath="..\atomic.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\base_drag_source.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\base_drag_source.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\base_drop_target.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\base_drop_target.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\base_paths.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\base_paths.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\base_switches.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\base_switches.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\basictypes.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\third_party\nss\blapi.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\third_party\nss\blapit.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\clipboard.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\clipboard.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\clipboard_util.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\clipboard_util.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\command_line.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\command_line.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\condition_variable.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\condition_variable.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\debug_on_start.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\debug_on_start.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\debug_util.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\debug_util.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\event_recorder.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\event_recorder.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\file_util.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\file_util.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\file_version_info.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\file_version_info.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\fix_wp64.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\fixed_string.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\histogram.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\histogram.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\hmac.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\hmac.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\iat_patch.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\iat_patch.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\icu_util.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\icu_util.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\id_map.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\idle_timer.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\idle_timer.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\image_util.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\image_util.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\json_reader.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\json_reader.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\json_writer.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\json_writer.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\linked_ptr.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\lock.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\lock.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\lock_impl.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\lock_impl_win.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\logging.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\logging.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\md5.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\md5.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\memory_debug.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\memory_debug.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\message_loop.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\message_loop.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\non_thread_safe.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\non_thread_safe.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\observer_list.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\path_service.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\path_service.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\pe_image.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\pe_image.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\pickle.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\pickle.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\platform_thread.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\platform_thread.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\port.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\third_party\nspr\prcpucfg.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\third_party\nspr\prcpucfg_win.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\process.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\process.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\process_util.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\process_util.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\third_party\nspr\prtime.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\third_party\nspr\prtime.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\third_party\nspr\prtypes.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\third_party\purify\pure.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\third_party\purify\pure_api.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\ref_counted.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\registry.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\registry.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\resource_util.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\resource_util.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\revocable_store.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\revocable_store.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\scoped_handle.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\scoped_ptr.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sha2.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sha2.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\third_party\nss\sha256.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\third_party\nss\sha512.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\shared_event.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\shared_event.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\shared_memory.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\shared_memory.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\singleton.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\singleton_internal.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\spin_wait.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\stack_container.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\stats_counters.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\stats_table.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\stats_table.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\string16.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\string_escape.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\string_escape.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\string_piece.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\string_piece.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\string_tokenizer.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\string_util.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\string_util.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\string_util_icu.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\string_util_win.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\string_util_win.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\task.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\thread.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\thread.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\thread_local_storage.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\thread_local_storage_win.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\time.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\time.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\time_win.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\timer.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\timer.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\tracked.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\tracked.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\tracked_objects.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\tracked_objects.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\tuple.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\values.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\values.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\watchdog.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\watchdog.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\win_util.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\win_util.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\windows_message_list.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\wmi_util.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\wmi_util.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\word_iterator.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\word_iterator.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\worker_pool.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\worker_pool.h"
|
||||
>
|
||||
</File>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
8
base/build/base.vsprops
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioPropertySheet
|
||||
ProjectType="Visual C++"
|
||||
Version="8.00"
|
||||
Name="base"
|
||||
InheritedPropertySheets="$(SolutionDir)..\build\common.vsprops;$(SolutionDir)..\third_party\icu38\build\using_icu.vsprops;$(SolutionDir)..\testing\using_gtest.vsprops"
|
||||
>
|
||||
</VisualStudioPropertySheet>
|
263
base/build/base_gfx.vcproj
Normal file
@ -0,0 +1,263 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="8.00"
|
||||
Name="base_gfx"
|
||||
ProjectGUID="{A508ADD3-CECE-4E0F-8448-2F5E454DF551}"
|
||||
RootNamespace="base_gfx"
|
||||
Keyword="Win32Proj"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
ConfigurationType="4"
|
||||
InheritedPropertySheets="$(SolutionDir)..\build\debug.vsprops;.\base_gfx.vsprops;..\..\skia\using_skia.vsprops"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
ConfigurationType="4"
|
||||
InheritedPropertySheets="$(SolutionDir)..\build\release.vsprops;.\base_gfx.vsprops;..\..\skia\using_skia.vsprops"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<File
|
||||
RelativePath="..\gfx\bitmap_header.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\gfx\bitmap_header.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\gfx\bitmap_platform_device.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\gfx\bitmap_platform_device.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\gfx\convolver.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\gfx\convolver.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\gfx\font_utils.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\gfx\font_utils.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\gfx\image_operations.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\gfx\image_operations.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\gfx\native_theme.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\gfx\native_theme.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\gfx\platform_canvas.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\gfx\platform_canvas.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\gfx\platform_device.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\gfx\platform_device.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\gfx\png_decoder.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\gfx\png_decoder.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\gfx\png_encoder.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\gfx\png_encoder.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\gfx\point.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\gfx\point.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\gfx\rect.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\gfx\rect.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\gfx\size.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\gfx\size.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\gfx\skia_utils.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\gfx\skia_utils.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\gfx\uniscribe.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\gfx\uniscribe.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\gfx\vector_canvas.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\gfx\vector_canvas.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\gfx\vector_device.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\gfx\vector_device.h"
|
||||
>
|
||||
</File>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
8
base/build/base_gfx.vsprops
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioPropertySheet
|
||||
ProjectType="Visual C++"
|
||||
Version="8.00"
|
||||
Name="base_gfx"
|
||||
InheritedPropertySheets="$(SolutionDir)..\build\common.vsprops;$(SolutionDir)..\third_party\icu38\build\using_icu.vsprops;$(SolutionDir)..\third_party\libpng\using_libpng.vsprops;$(SolutionDir)..\third_party\zlib\using_zlib.vsprops;..\..\skia\using_skia.vsprops"
|
||||
>
|
||||
</VisualStudioPropertySheet>
|
370
base/build/base_unittests.vcproj
Normal file
@ -0,0 +1,370 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="8.00"
|
||||
Name="base_unittests"
|
||||
ProjectGUID="{27A30967-4BBA-48D1-8522-CDE95F7B1CEC}"
|
||||
RootNamespace="base_unittests"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
ConfigurationType="1"
|
||||
InheritedPropertySheets="$(SolutionDir)..\build\debug.vsprops;.\base_unittests.vsprops;$(SolutionDir)..\testing\using_gtest.vsprops"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions="UNIT_TEST"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
ConfigurationType="1"
|
||||
InheritedPropertySheets="$(SolutionDir)..\build\release.vsprops;.\base_unittests.vsprops;$(SolutionDir)..\testing\using_gtest.vsprops"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions="UNIT_TEST"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="support"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\check_handler.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\multiprocess_test.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\no_windows2000_unittest.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\run_all_unittests.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\test_suite.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="base_tests"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\atomic_unittest.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\check_handler_unittest.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\clipboard_unittest.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\command_line_unittest.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\condition_variable_test.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\file_util_unittest.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\file_version_info_unittest.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\fixed_string_unittest.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\histogram_test.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\hmac_unittest.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\idletimer_unittest.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\json_reader_unittest.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\json_writer_unittest.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\linked_ptr_unittest.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\message_loop_unittest.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\gfx\native_theme_unittest.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\path_service_unittest.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\pe_image_unittest.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\pickle_unittest.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\pr_time_test.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\process_util_unittest.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\gfx\rect_unittest.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\ref_counted_unittest.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sha2_unittest.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\shared_event_unittest.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\shared_memory_unittest.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\singleton_unittest.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\stack_container_unittest.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\stats_table_unittest.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\string_escape_unittest.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\string_piece_unittest.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\string_tokenizer_unittest.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\string_util_unittest.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\thread_local_storage_unittest.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\thread_unittest.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\time_unittest.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\timer_unittest.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\tracked_objects_test.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\values_unittest.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\watchdog_test.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\win_util_unittest.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\wmi_util_unittest.cc"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="gfx_tests"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\gfx\convolver_unittest.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\gfx\image_operations_unittest.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\gfx\platform_canvas_unittest.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\gfx\png_codec_unittest.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\gfx\uniscribe_unittest.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\gfx\vector_canvas_unittest.cc"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
8
base/build/base_unittests.vsprops
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioPropertySheet
|
||||
ProjectType="Visual C++"
|
||||
Version="8.00"
|
||||
Name="base_unittests"
|
||||
InheritedPropertySheets=".\base_gfx.vsprops"
|
||||
>
|
||||
</VisualStudioPropertySheet>
|
151
base/build/debug_message.vcproj
Normal file
@ -0,0 +1,151 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="8.00"
|
||||
Name="debug_message"
|
||||
ProjectGUID="{0E5474AC-5996-4B13-87C0-4AE931EE0815}"
|
||||
RootNamespace="DebugMessage"
|
||||
Keyword="Win32Proj"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
ConfigurationType="1"
|
||||
InheritedPropertySheets="$(SolutionDir)..\build\common.vsprops;$(SolutionDir)..\build\debug.vsprops"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
SubSystem="2"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
ConfigurationType="1"
|
||||
InheritedPropertySheets="$(SolutionDir)..\build\common.vsprops;$(SolutionDir)..\build\release.vsprops"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
SubSystem="2"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<File
|
||||
RelativePath="..\debug_message.cc"
|
||||
>
|
||||
</File>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
9
base/build/singleton_dll_unittest.def
Normal file
@ -0,0 +1,9 @@
|
||||
EXPORTS
|
||||
SingletonInt1
|
||||
SingletonInt2
|
||||
SingletonInt3
|
||||
SingletonInt4
|
||||
SingletonInt5
|
||||
SingletonNoLeak
|
||||
SingletonLeak
|
||||
GetLeakySingleton
|
15
base/build/singleton_dll_unittest.vsprops
Normal file
@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioPropertySheet
|
||||
ProjectType="Visual C++"
|
||||
Version="8.00"
|
||||
Name="singleton_dll_unittest"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions="SINGLETON_UNITTEST_EXPORTS"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
ModuleDefinitionFile="singleton_dll_unittest.def"
|
||||
/>
|
||||
</VisualStudioPropertySheet>
|
157
base/build/singleton_unittest.vcproj
Normal file
@ -0,0 +1,157 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="8.00"
|
||||
Name="singleton_dll_unittest"
|
||||
ProjectGUID="{E457F2FB-4708-4001-9B1C-275D7BD7F2A8}"
|
||||
RootNamespace="singleton_unittest"
|
||||
Keyword="Win32Proj"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
ConfigurationType="2"
|
||||
InheritedPropertySheets="$(SolutionDir)..\build\debug.vsprops;.\singleton_dll_unittest.vsprops"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
ConfigurationType="2"
|
||||
InheritedPropertySheets="$(SolutionDir)..\build\release.vsprops;.\singleton_dll_unittest.vsprops"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<File
|
||||
RelativePath="..\singleton_dll_unittest.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\singleton_dll_unittest.def"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\singleton_dll_unittest.h"
|
||||
>
|
||||
</File>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
112
base/check_handler.h
Normal file
@ -0,0 +1,112 @@
|
||||
// Copyright 2008, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#ifndef BASE_CHECK_HANDLER_H__
|
||||
#define BASE_CHECK_HANDLER_H__
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include "base/logging.h"
|
||||
|
||||
// This class allows temporary handling of assert firing. When a CHECK()
|
||||
// or DCHECK() assertion happens it will in turn generate a SEH exception
|
||||
// which can be can captured using a windows SEH hander __try .. _except
|
||||
// block. One practical use of this class is for unit tests that make sure
|
||||
// CHECK conditions are appropriately handled. For example:
|
||||
//
|
||||
// TEST(TestGroup, VerifyAssert) {
|
||||
// CheckAssertHandler expect_exception;
|
||||
// __try {
|
||||
// MyClass object; // MyClass dtor will not be called.
|
||||
// Param some_bad_param;
|
||||
// object.Method(some_bad_param); // Should triggers a CHECK().
|
||||
// ADD_FAILURE(); // If we get here the test failed.
|
||||
// } __except(EXCEPTION_EXECUTE_HANDLER) {
|
||||
// DWORD ecode = GetExceptionCode();
|
||||
// EXPECT_EQ(CheckAssertHandler::seh_exception_code(), ecode);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// You can put MyClass outside the __try block so its destructor will be
|
||||
// called which could lead to a crash if the state of the object is
|
||||
// corrupted by the CHECK you are testing. If that is the case you should
|
||||
// fix the state of the object inside the __except block.
|
||||
//
|
||||
// Since the above code is Windows specific, two helper macros are provided
|
||||
// that hide the implementation details. Using the macros the code becomes:
|
||||
//
|
||||
// TEST(TestGroup, VerifyAssert) {
|
||||
// CHECK_HANDLER_BEGIN
|
||||
// MyClass object; // MyClass dtor will not be called.
|
||||
// Param some_bad_param;
|
||||
// object.Method(some_bad_param); // Should triggers a CHECK().
|
||||
// CHECK_HANDLER_END
|
||||
// }
|
||||
//
|
||||
// Depending on the compiler settings you might have issue this pragma arround
|
||||
// the code that uses this class:
|
||||
// #pragma warning(disable: 4509)
|
||||
// Which tells the compiler that is ok that some dtors will not be called.
|
||||
//
|
||||
// Create this object on the stack always.Do not create it inside the
|
||||
// __try block itself or the dtor will never be called. Create only one
|
||||
// on each scope.
|
||||
//
|
||||
// The key detail here is the RaiseException() call which transfers
|
||||
// program control away from the code that caused the assertion and back
|
||||
// into the _except block.
|
||||
|
||||
class CheckAssertHandler {
|
||||
public:
|
||||
// Installs the assert handler. The dtor will remove the handler.
|
||||
CheckAssertHandler() {
|
||||
logging::SetLogAssertHandler(&CheckAssertHandler::LogAssertHandler);
|
||||
}
|
||||
~CheckAssertHandler() {
|
||||
logging::SetLogAssertHandler(NULL);
|
||||
}
|
||||
static DWORD seh_exception_code() { return 0x1765413; }
|
||||
private:
|
||||
static void LogAssertHandler(const std::string&) {
|
||||
::RaiseException(seh_exception_code(), 0, 0, NULL);
|
||||
}
|
||||
};
|
||||
|
||||
#define CHECK_HANDLER_BEGIN \
|
||||
CheckAssertHandler chk_ex_handler; \
|
||||
__try {
|
||||
|
||||
#define CHECK_HANDLER_END \
|
||||
ADD_FAILURE(); \
|
||||
} __except(EXCEPTION_EXECUTE_HANDLER) { \
|
||||
DWORD ecode = GetExceptionCode(); \
|
||||
EXPECT_EQ(CheckAssertHandler::seh_exception_code(), ecode); \
|
||||
}
|
||||
|
||||
#endif // BASE_CHECK_HANDLER_H__
|
72
base/check_handler_unittest.cc
Normal file
@ -0,0 +1,72 @@
|
||||
// Copyright 2008, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include "base/check_handler.h"
|
||||
#include "base/logging.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
|
||||
namespace {
|
||||
|
||||
class SimpleTestClass {
|
||||
public:
|
||||
SimpleTestClass() {
|
||||
}
|
||||
~SimpleTestClass() {
|
||||
ADD_FAILURE();
|
||||
}
|
||||
void ThisMethodAsserts() {
|
||||
CHECK(false);
|
||||
ADD_FAILURE();
|
||||
}
|
||||
};
|
||||
|
||||
void ThisFunctionAsserts() {
|
||||
CHECK(false);
|
||||
ADD_FAILURE();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 4509)
|
||||
|
||||
TEST(CheckHandlerTest, TestMacroCheckObj) {
|
||||
CHECK_HANDLER_BEGIN
|
||||
SimpleTestClass object;
|
||||
object.ThisMethodAsserts();
|
||||
CHECK_HANDLER_END
|
||||
}
|
||||
|
||||
TEST(CheckHandlerTest, TestMacroCheckFunc) {
|
||||
CHECK_HANDLER_BEGIN
|
||||
ThisFunctionAsserts();
|
||||
CHECK_HANDLER_END
|
||||
}
|
||||
|
||||
#pragma warning(pop)
|
658
base/clipboard.cc
Normal file
@ -0,0 +1,658 @@
|
||||
// Copyright 2008, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Many of these functions are based on those found in
|
||||
// webkit/port/platform/PasteboardWin.cpp
|
||||
|
||||
#include <shlobj.h>
|
||||
#include <shellapi.h>
|
||||
|
||||
#include "base/clipboard.h"
|
||||
|
||||
#include "base/clipboard_util.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/string_util.h"
|
||||
|
||||
namespace {
|
||||
|
||||
// A small object to ensure we close the clipboard after opening it.
|
||||
class ClipboardLock {
|
||||
public:
|
||||
ClipboardLock() : we_own_the_lock_(false) { }
|
||||
|
||||
~ClipboardLock() {
|
||||
if (we_own_the_lock_)
|
||||
Release();
|
||||
}
|
||||
|
||||
bool Acquire(HWND owner) {
|
||||
// We shouldn't be calling this if we already own the clipbard lock.
|
||||
DCHECK(!we_own_the_lock_);
|
||||
|
||||
// We already have the lock. We don't want to stomp on the other use.
|
||||
if (we_own_the_lock_)
|
||||
return false;
|
||||
|
||||
const int kMaxAttemptsToOpenClipboard = 5;
|
||||
|
||||
// Attempt to acquire the clipboard lock. This may fail if another process
|
||||
// currently holds the lock. We're willing to try a few times in the hopes
|
||||
// of acquiring it.
|
||||
//
|
||||
// This turns out to be an issue when using remote desktop because the
|
||||
// rdpclip.exe process likes to read what we've written to the clipboard and
|
||||
// send it to the RDP client. If we open and close the clipboard in quick
|
||||
// succession, we might be trying to open it while rdpclip.exe has it open,
|
||||
// See Bug 815425.
|
||||
//
|
||||
// In fact, we believe we'll only spin this loop over remote desktop. In
|
||||
// normal situations, the user is initiating clipboard operations and there
|
||||
// shouldn't be lock contention.
|
||||
|
||||
for (int attempts = 0; attempts < kMaxAttemptsToOpenClipboard; ++attempts) {
|
||||
if (::OpenClipboard(owner)) {
|
||||
we_own_the_lock_ = true;
|
||||
return we_own_the_lock_;
|
||||
}
|
||||
|
||||
// Having failed, we yeild our timeslice to other processes. ::Yield seems
|
||||
// to be insufficient here, so we sleep for 5 ms.
|
||||
if (attempts < (kMaxAttemptsToOpenClipboard - 1))
|
||||
::Sleep(5);
|
||||
}
|
||||
|
||||
// We failed to acquire the clipboard.
|
||||
return false;
|
||||
}
|
||||
|
||||
void Release() {
|
||||
// We should only be calling this if we already own the clipbard lock.
|
||||
DCHECK(we_own_the_lock_);
|
||||
|
||||
// We we don't have the lock, there is nothing to release.
|
||||
if (!we_own_the_lock_)
|
||||
return;
|
||||
|
||||
::CloseClipboard();
|
||||
we_own_the_lock_ = false;
|
||||
}
|
||||
|
||||
private:
|
||||
bool we_own_the_lock_;
|
||||
};
|
||||
|
||||
LRESULT CALLBACK ClipboardOwnerWndProc(HWND hwnd,
|
||||
UINT message,
|
||||
WPARAM wparam,
|
||||
LPARAM lparam) {
|
||||
LRESULT lresult = 0;
|
||||
|
||||
switch(message) {
|
||||
case WM_RENDERFORMAT:
|
||||
// This message comes when SetClipboardData was sent a null data handle
|
||||
// and now it's come time to put the data on the clipboard.
|
||||
// We always set data, so there isn't a need to actually do anything here.
|
||||
break;
|
||||
case WM_RENDERALLFORMATS:
|
||||
// This message comes when SetClipboardData was sent a null data handle
|
||||
// and now this application is about to quit, so it must put data on
|
||||
// the clipboard before it exits.
|
||||
// We always set data, so there isn't a need to actually do anything here.
|
||||
break;
|
||||
case WM_DRAWCLIPBOARD:
|
||||
break;
|
||||
case WM_DESTROY:
|
||||
break;
|
||||
case WM_CHANGECBCHAIN:
|
||||
break;
|
||||
default:
|
||||
lresult = DefWindowProc(hwnd, message, wparam, lparam);
|
||||
break;
|
||||
}
|
||||
return lresult;
|
||||
}
|
||||
|
||||
template <typename charT>
|
||||
HGLOBAL CreateGlobalData(const std::basic_string<charT>& str) {
|
||||
HGLOBAL data =
|
||||
::GlobalAlloc(GMEM_MOVEABLE, ((str.size() + 1) * sizeof(charT)));
|
||||
if (data) {
|
||||
charT* raw_data = static_cast<charT*>(::GlobalLock(data));
|
||||
memcpy(raw_data, str.data(), str.size() * sizeof(charT));
|
||||
raw_data[str.size()] = '\0';
|
||||
::GlobalUnlock(data);
|
||||
}
|
||||
return data;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
Clipboard::Clipboard() {
|
||||
// make a dummy HWND to be the clipboard's owner
|
||||
WNDCLASSEX wcex = {0};
|
||||
wcex.cbSize = sizeof(WNDCLASSEX);
|
||||
wcex.lpfnWndProc = ClipboardOwnerWndProc;
|
||||
wcex.hInstance = GetModuleHandle(NULL);
|
||||
wcex.lpszClassName = L"ClipboardOwnerWindowClass";
|
||||
::RegisterClassEx(&wcex);
|
||||
|
||||
clipboard_owner_ = ::CreateWindow(L"ClipboardOwnerWindowClass",
|
||||
L"ClipboardOwnerWindow",
|
||||
0, 0, 0, 0, 0,
|
||||
HWND_MESSAGE,
|
||||
0, 0, 0);
|
||||
}
|
||||
|
||||
Clipboard::~Clipboard() {
|
||||
::DestroyWindow(clipboard_owner_);
|
||||
clipboard_owner_ = NULL;
|
||||
}
|
||||
|
||||
void Clipboard::Clear() const {
|
||||
// Acquire the clipboard.
|
||||
ClipboardLock lock;
|
||||
if (!lock.Acquire(clipboard_owner_))
|
||||
return;
|
||||
|
||||
::EmptyClipboard();
|
||||
}
|
||||
|
||||
void Clipboard::WriteText(const std::wstring& text) const {
|
||||
ClipboardLock lock;
|
||||
if (!lock.Acquire(clipboard_owner_))
|
||||
return;
|
||||
|
||||
HGLOBAL glob = CreateGlobalData(text);
|
||||
if (glob && !::SetClipboardData(CF_UNICODETEXT, glob))
|
||||
::GlobalFree(glob);
|
||||
}
|
||||
|
||||
void Clipboard::WriteHTML(const std::wstring& markup,
|
||||
const std::string& url) const {
|
||||
// Acquire the clipboard.
|
||||
ClipboardLock lock;
|
||||
if (!lock.Acquire(clipboard_owner_))
|
||||
return;
|
||||
|
||||
std::string html_fragment;
|
||||
MarkupToHTMLClipboardFormat(markup, url, &html_fragment);
|
||||
HGLOBAL glob = CreateGlobalData(html_fragment);
|
||||
if (glob && !::SetClipboardData(ClipboardUtil::GetHtmlFormat()->cfFormat,
|
||||
glob)) {
|
||||
::GlobalFree(glob);
|
||||
}
|
||||
}
|
||||
|
||||
void Clipboard::WriteBookmark(const std::wstring& title,
|
||||
const std::string& url) const {
|
||||
// Acquire the clipboard.
|
||||
ClipboardLock lock;
|
||||
if (!lock.Acquire(clipboard_owner_))
|
||||
return;
|
||||
|
||||
std::wstring bookmark(title);
|
||||
bookmark.append(1, L'\n');
|
||||
bookmark.append(UTF8ToWide(url));
|
||||
HGLOBAL glob = CreateGlobalData(bookmark);
|
||||
if (glob && !::SetClipboardData(ClipboardUtil::GetUrlWFormat()->cfFormat,
|
||||
glob)) {
|
||||
::GlobalFree(glob);
|
||||
}
|
||||
}
|
||||
|
||||
void Clipboard::WriteHyperlink(const std::wstring& title,
|
||||
const std::string& url) const {
|
||||
// Write as a bookmark.
|
||||
WriteBookmark(title, url);
|
||||
|
||||
// Build the HTML link.
|
||||
std::wstring link(L"<a href=\"");
|
||||
link.append(UTF8ToWide(url));
|
||||
link.append(L"\">");
|
||||
link.append(title);
|
||||
link.append(L"</a>");
|
||||
|
||||
// Write as an HTML link.
|
||||
WriteHTML(link, std::string());
|
||||
}
|
||||
|
||||
void Clipboard::WriteWebSmartPaste() const {
|
||||
// Acquire the clipboard.
|
||||
ClipboardLock lock;
|
||||
if (!lock.Acquire(clipboard_owner_))
|
||||
return;
|
||||
|
||||
SetClipboardData(ClipboardUtil::GetWebKitSmartPasteFormat()->cfFormat, NULL);
|
||||
}
|
||||
|
||||
void Clipboard::WriteBitmap(const void* pixels, const gfx::Size& size) const {
|
||||
HDC dc = ::GetDC(NULL);
|
||||
|
||||
// This doesn't actually cost us a memcpy when the bitmap comes from the
|
||||
// renderer as we load it into the bitmap using setPixels which just sets a
|
||||
// pointer. Someone has to memcpy it into GDI, it might as well be us here.
|
||||
|
||||
// TODO(darin): share data in gfx/bitmap_header.cc somehow
|
||||
BITMAPINFO bm_info = {0};
|
||||
bm_info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
||||
bm_info.bmiHeader.biWidth = size.width();
|
||||
bm_info.bmiHeader.biHeight = -size.height(); // sets vertical orientation
|
||||
bm_info.bmiHeader.biPlanes = 1;
|
||||
bm_info.bmiHeader.biBitCount = 32;
|
||||
bm_info.bmiHeader.biCompression = BI_RGB;
|
||||
|
||||
// ::CreateDIBSection allocates memory for us to copy our bitmap into.
|
||||
// Unfortunately, we can't write the created bitmap to the clipboard,
|
||||
// (see http://msdn2.microsoft.com/en-us/library/ms532292.aspx)
|
||||
void *bits;
|
||||
HBITMAP source_hbitmap =
|
||||
::CreateDIBSection(dc, &bm_info, DIB_RGB_COLORS, &bits, NULL, 0);
|
||||
|
||||
if (bits && source_hbitmap) {
|
||||
// Copy the bitmap out of shared memory and into GDI
|
||||
memcpy(bits, pixels, 4 * size.width() * size.height());
|
||||
|
||||
// Now we have an HBITMAP, we can write it to the clipboard
|
||||
WriteBitmapFromHandle(source_hbitmap, size);
|
||||
}
|
||||
|
||||
::DeleteObject(source_hbitmap);
|
||||
::ReleaseDC(NULL, dc);
|
||||
}
|
||||
|
||||
void Clipboard::WriteBitmapFromSharedMemory(const SharedMemory& bitmap,
|
||||
const gfx::Size& size) const {
|
||||
// TODO(darin): share data in gfx/bitmap_header.cc somehow
|
||||
BITMAPINFO bm_info = {0};
|
||||
bm_info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
||||
bm_info.bmiHeader.biWidth = size.width();
|
||||
bm_info.bmiHeader.biHeight = -size.height(); // Sets the vertical orientation
|
||||
bm_info.bmiHeader.biPlanes = 1;
|
||||
bm_info.bmiHeader.biBitCount = 32;
|
||||
bm_info.bmiHeader.biCompression = BI_RGB;
|
||||
|
||||
HDC dc = ::GetDC(NULL);
|
||||
|
||||
// We can create an HBITMAP directly using the shared memory handle, saving
|
||||
// a memcpy.
|
||||
HBITMAP source_hbitmap =
|
||||
::CreateDIBSection(dc, &bm_info, DIB_RGB_COLORS, NULL, bitmap.handle(), 0);
|
||||
|
||||
if (source_hbitmap) {
|
||||
// Now we can write the HBITMAP to the clipboard
|
||||
WriteBitmapFromHandle(source_hbitmap, size);
|
||||
}
|
||||
|
||||
::DeleteObject(source_hbitmap);
|
||||
::ReleaseDC(NULL, dc);
|
||||
}
|
||||
|
||||
void Clipboard::WriteBitmapFromHandle(HBITMAP source_hbitmap,
|
||||
const gfx::Size& size) const {
|
||||
// Acquire the clipboard.
|
||||
ClipboardLock lock;
|
||||
if (!lock.Acquire(clipboard_owner_))
|
||||
return;
|
||||
|
||||
// We would like to just call ::SetClipboardData on the source_hbitmap,
|
||||
// but that bitmap might not be of a sort we can write to the clipboard.
|
||||
// For this reason, we create a new bitmap, copy the bits over, and then
|
||||
// write that to the clipboard.
|
||||
|
||||
HDC dc = ::GetDC(NULL);
|
||||
HDC compatible_dc = ::CreateCompatibleDC(NULL);
|
||||
HDC source_dc = ::CreateCompatibleDC(NULL);
|
||||
|
||||
// This is the HBITMAP we will eventually write to the clipboard
|
||||
HBITMAP hbitmap = ::CreateCompatibleBitmap(dc, size.width(), size.height());
|
||||
if (!hbitmap) {
|
||||
// Failed to create the bitmap
|
||||
::DeleteDC(compatible_dc);
|
||||
::DeleteDC(source_dc);
|
||||
::ReleaseDC(NULL, dc);
|
||||
return;
|
||||
}
|
||||
|
||||
HBITMAP old_hbitmap = (HBITMAP)SelectObject(compatible_dc, hbitmap);
|
||||
HBITMAP old_source = (HBITMAP)SelectObject(source_dc, source_hbitmap);
|
||||
|
||||
// Now we need to blend it into an HBITMAP we can place on the clipboard
|
||||
BLENDFUNCTION bf = {AC_SRC_OVER, 0, 255, AC_SRC_ALPHA};
|
||||
::AlphaBlend(compatible_dc, 0, 0, size.width(), size.height(),
|
||||
source_dc, 0, 0, size.width(), size.height(), bf);
|
||||
|
||||
// Clean up all the handles we just opened
|
||||
::SelectObject(compatible_dc, old_hbitmap);
|
||||
::SelectObject(source_dc, old_source);
|
||||
::DeleteObject(old_hbitmap);
|
||||
::DeleteObject(old_source);
|
||||
::DeleteDC(compatible_dc);
|
||||
::DeleteDC(source_dc);
|
||||
::ReleaseDC(NULL, dc);
|
||||
|
||||
// Actually write the bitmap to the clipboard
|
||||
::SetClipboardData(CF_BITMAP, hbitmap);
|
||||
}
|
||||
|
||||
// Write a file or set of files to the clipboard in HDROP format. When the user
|
||||
// invokes a paste command (in a Windows explorer shell, for example), the files
|
||||
// will be copied to the paste location.
|
||||
void Clipboard::WriteFile(const std::wstring& file) const {
|
||||
std::vector<std::wstring> files;
|
||||
files.push_back(file);
|
||||
WriteFiles(files);
|
||||
}
|
||||
|
||||
void Clipboard::WriteFiles(const std::vector<std::wstring>& files) const {
|
||||
ClipboardLock lock;
|
||||
if (!lock.Acquire(clipboard_owner_))
|
||||
return;
|
||||
|
||||
// Calculate the amount of space we'll need store the strings: require
|
||||
// NULL terminator between strings, and double null terminator at the end.
|
||||
size_t bytes = sizeof(DROPFILES);
|
||||
for (size_t i = 0; i < files.size(); ++i)
|
||||
bytes += (files[i].length() + 1) * sizeof(wchar_t);
|
||||
bytes += sizeof(wchar_t);
|
||||
|
||||
HANDLE hdata = ::GlobalAlloc(GMEM_MOVEABLE, bytes);
|
||||
if (!hdata)
|
||||
return;
|
||||
|
||||
DROPFILES* drop_files = static_cast<DROPFILES*>(::GlobalLock(hdata));
|
||||
drop_files->pFiles = sizeof(DROPFILES);
|
||||
drop_files->fWide = TRUE;
|
||||
BYTE* data = reinterpret_cast<BYTE*>(drop_files) + sizeof(DROPFILES);
|
||||
|
||||
// Copy the strings stored in 'files' with proper NULL separation.
|
||||
wchar_t* data_pos = reinterpret_cast<wchar_t*>(data);
|
||||
for (size_t i = 0; i < files.size(); ++i) {
|
||||
size_t offset = files[i].length() + 1;
|
||||
memcpy(data_pos, files[i].c_str(), offset * sizeof(wchar_t));
|
||||
data_pos += offset;
|
||||
}
|
||||
data_pos[0] = L'\0'; // Double NULL termination after the last string.
|
||||
|
||||
::GlobalUnlock(hdata);
|
||||
if (!::SetClipboardData(CF_HDROP, hdata))
|
||||
::GlobalFree(hdata);
|
||||
}
|
||||
|
||||
bool Clipboard::IsFormatAvailable(unsigned int format) const {
|
||||
return ::IsClipboardFormatAvailable(format) != FALSE;
|
||||
}
|
||||
|
||||
void Clipboard::ReadText(std::wstring* result) const {
|
||||
if (!result) {
|
||||
NOTREACHED();
|
||||
return;
|
||||
}
|
||||
|
||||
result->clear();
|
||||
|
||||
// Acquire the clipboard.
|
||||
ClipboardLock lock;
|
||||
if (!lock.Acquire(clipboard_owner_))
|
||||
return;
|
||||
|
||||
HANDLE data = ::GetClipboardData(CF_UNICODETEXT);
|
||||
if (!data)
|
||||
return;
|
||||
|
||||
result->assign(static_cast<const wchar_t*>(::GlobalLock(data)));
|
||||
::GlobalUnlock(data);
|
||||
}
|
||||
|
||||
void Clipboard::ReadAsciiText(std::string* result) const {
|
||||
if (!result) {
|
||||
NOTREACHED();
|
||||
return;
|
||||
}
|
||||
|
||||
result->clear();
|
||||
|
||||
// Acquire the clipboard.
|
||||
ClipboardLock lock;
|
||||
if (!lock.Acquire(clipboard_owner_))
|
||||
return;
|
||||
|
||||
HANDLE data = ::GetClipboardData(CF_TEXT);
|
||||
if (!data)
|
||||
return;
|
||||
|
||||
result->assign(static_cast<const char*>(::GlobalLock(data)));
|
||||
::GlobalUnlock(data);
|
||||
}
|
||||
|
||||
void Clipboard::ReadHTML(std::wstring* markup, std::string* src_url) const {
|
||||
if (markup)
|
||||
markup->clear();
|
||||
|
||||
if (src_url)
|
||||
src_url->clear();
|
||||
|
||||
// Acquire the clipboard.
|
||||
ClipboardLock lock;
|
||||
if (!lock.Acquire(clipboard_owner_))
|
||||
return;
|
||||
|
||||
HANDLE data = ::GetClipboardData(ClipboardUtil::GetHtmlFormat()->cfFormat);
|
||||
if (!data)
|
||||
return;
|
||||
|
||||
std::string html_fragment(static_cast<const char*>(::GlobalLock(data)));
|
||||
::GlobalUnlock(data);
|
||||
|
||||
ParseHTMLClipboardFormat(html_fragment, markup, src_url);
|
||||
}
|
||||
|
||||
void Clipboard::ReadBookmark(std::wstring* title, std::string* url) const {
|
||||
if (title)
|
||||
title->clear();
|
||||
|
||||
if (url)
|
||||
url->clear();
|
||||
|
||||
// Acquire the clipboard.
|
||||
ClipboardLock lock;
|
||||
if (!lock.Acquire(clipboard_owner_))
|
||||
return;
|
||||
|
||||
HANDLE data = ::GetClipboardData(ClipboardUtil::GetUrlWFormat()->cfFormat);
|
||||
if (!data)
|
||||
return;
|
||||
|
||||
std::wstring bookmark(static_cast<const wchar_t*>(::GlobalLock(data)));
|
||||
::GlobalUnlock(data);
|
||||
|
||||
ParseBookmarkClipboardFormat(bookmark, title, url);
|
||||
}
|
||||
|
||||
// Read a file in HDROP format from the clipboard.
|
||||
void Clipboard::ReadFile(std::wstring* file) const {
|
||||
if (!file) {
|
||||
NOTREACHED();
|
||||
return;
|
||||
}
|
||||
|
||||
file->clear();
|
||||
std::vector<std::wstring> files;
|
||||
ReadFiles(&files);
|
||||
|
||||
// Take the first file, if available.
|
||||
if (!files.empty())
|
||||
file->assign(files[0]);
|
||||
}
|
||||
|
||||
// Read a set of files in HDROP format from the clipboard.
|
||||
void Clipboard::ReadFiles(std::vector<std::wstring>* files) const {
|
||||
if (!files) {
|
||||
NOTREACHED();
|
||||
return;
|
||||
}
|
||||
|
||||
files->clear();
|
||||
|
||||
ClipboardLock lock;
|
||||
if (!lock.Acquire(clipboard_owner_))
|
||||
return;
|
||||
|
||||
HDROP drop = static_cast<HDROP>(::GetClipboardData(CF_HDROP));
|
||||
if (!drop)
|
||||
return;
|
||||
|
||||
// Count of files in the HDROP.
|
||||
int count = ::DragQueryFile(drop, 0xffffffff, NULL, 0);
|
||||
|
||||
if (count) {
|
||||
for (int i = 0; i < count; ++i) {
|
||||
int size = ::DragQueryFile(drop, i, NULL, 0) + 1;
|
||||
std::wstring file;
|
||||
::DragQueryFile(drop, i, WriteInto(&file, size), size);
|
||||
files->push_back(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void Clipboard::MarkupToHTMLClipboardFormat(const std::wstring& markup,
|
||||
const std::string& src_url,
|
||||
std::string* html_fragment) {
|
||||
DCHECK(html_fragment);
|
||||
// Documentation for the CF_HTML format is available at
|
||||
// http://msdn.microsoft.com/workshop/networking/clipboard/htmlclipboard.asp
|
||||
|
||||
if (markup.empty()) {
|
||||
html_fragment->clear();
|
||||
return;
|
||||
}
|
||||
|
||||
std::string markup_utf8 = WideToUTF8(markup);
|
||||
|
||||
html_fragment->assign("Version:0.9");
|
||||
|
||||
std::string start_html("\nStartHTML:");
|
||||
std::string end_html("\nEndHTML:");
|
||||
std::string start_fragment("\nStartFragment:");
|
||||
std::string end_fragment("\nEndFragment:");
|
||||
std::string source_url("\nSourceURL:");
|
||||
|
||||
bool has_source_url = !src_url.empty() &&
|
||||
!StartsWithASCII(src_url, "about:", false);
|
||||
if (has_source_url)
|
||||
source_url.append(src_url);
|
||||
|
||||
std::string start_markup("\n<HTML>\n<BODY>\n<!--StartFragment-->\n");
|
||||
std::string end_markup("\n<!--EndFragment-->\n</BODY>\n</HTML>");
|
||||
|
||||
// calculate offsets
|
||||
const size_t kMaxDigits = 10; // number of digits in UINT_MAX in base 10
|
||||
|
||||
size_t start_html_offset, start_fragment_offset;
|
||||
size_t end_fragment_offset, end_html_offset;
|
||||
|
||||
start_html_offset = html_fragment->length() +
|
||||
start_html.length() + end_html.length() +
|
||||
start_fragment.length() + end_fragment.length() +
|
||||
(has_source_url ? source_url.length() : 0) +
|
||||
(4*kMaxDigits);
|
||||
|
||||
start_fragment_offset = start_html_offset + start_markup.length();
|
||||
end_fragment_offset = start_fragment_offset + markup_utf8.length();
|
||||
end_html_offset = end_fragment_offset + end_markup.length();
|
||||
|
||||
// fill in needed data
|
||||
start_html.append(StringPrintf("%010u", start_html_offset));
|
||||
end_html.append(StringPrintf("%010u", end_html_offset));
|
||||
start_fragment.append(StringPrintf("%010u", start_fragment_offset));
|
||||
end_fragment.append(StringPrintf("%010u", end_fragment_offset));
|
||||
start_markup.append(markup_utf8);
|
||||
|
||||
// create full html_fragment string from the fragments
|
||||
html_fragment->append(start_html);
|
||||
html_fragment->append(end_html);
|
||||
html_fragment->append(start_fragment);
|
||||
html_fragment->append(end_fragment);
|
||||
if (has_source_url)
|
||||
html_fragment->append(source_url);
|
||||
html_fragment->append(start_markup);
|
||||
html_fragment->append(end_markup);
|
||||
}
|
||||
|
||||
// static
|
||||
void Clipboard::ParseHTMLClipboardFormat(const std::string& html_frag,
|
||||
std::wstring* markup,
|
||||
std::string* src_url) {
|
||||
if (src_url) {
|
||||
// Obtain SourceURL, if present
|
||||
std::string src_url_str("SourceURL:");
|
||||
size_t line_start = html_frag.find(src_url_str, 0);
|
||||
if (line_start != std::string::npos) {
|
||||
size_t src_start = line_start+src_url_str.length();
|
||||
size_t src_end = html_frag.find("\n", line_start);
|
||||
|
||||
if (src_end != std::string::npos)
|
||||
*src_url = html_frag.substr(src_start, src_end - src_start);
|
||||
}
|
||||
}
|
||||
|
||||
if (markup) {
|
||||
// Find the markup between "<!--StartFragment -->" and
|
||||
// "<!--EndFragment -->", accounting for browser quirks
|
||||
size_t markup_start = html_frag.find('<', 0);
|
||||
size_t tag_start = html_frag.find("StartFragment", markup_start);
|
||||
size_t frag_start = html_frag.find('>', tag_start) + 1;
|
||||
// Here we do something slightly differently than WebKit. Webkit does a
|
||||
// forward find for EndFragment, but that seems to be a bug if the html
|
||||
// fragment actually includes the string "EndFragment"
|
||||
size_t tag_end = html_frag.rfind("EndFragment", std::string::npos);
|
||||
size_t frag_end = html_frag.rfind('<', tag_end);
|
||||
|
||||
TrimWhitespace(UTF8ToWide(html_frag.substr(frag_start,
|
||||
frag_end - frag_start)),
|
||||
TRIM_ALL, markup);
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void Clipboard::ParseBookmarkClipboardFormat(const std::wstring& bookmark,
|
||||
std::wstring* title,
|
||||
std::string* url) {
|
||||
const wchar_t* const kDelim = L"\r\n";
|
||||
|
||||
const size_t title_end = bookmark.find_first_of(kDelim);
|
||||
if (title)
|
||||
title->assign(bookmark.substr(0, title_end));
|
||||
|
||||
if (url) {
|
||||
const size_t url_start = bookmark.find_first_not_of(kDelim, title_end);
|
||||
if (url_start != std::wstring::npos)
|
||||
*url = WideToUTF8(bookmark.substr(url_start, std::wstring::npos));
|
||||
}
|
||||
}
|
126
base/clipboard.h
Normal file
@ -0,0 +1,126 @@
|
||||
// Copyright 2008, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#ifndef BASE_CLIPBOARD_H__
|
||||
#define BASE_CLIPBOARD_H__
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include "base/gfx/size.h"
|
||||
#include "base/shared_memory.h"
|
||||
|
||||
class Clipboard {
|
||||
public:
|
||||
Clipboard();
|
||||
~Clipboard();
|
||||
|
||||
// Clears the clipboard. It is usually a good idea to clear the clipboard
|
||||
// before writing content to the clipboard.
|
||||
void Clear() const;
|
||||
|
||||
// Adds UNICODE and ASCII text to the clipboard.
|
||||
void WriteText(const std::wstring& text) const;
|
||||
|
||||
// Adds HTML to the clipboard. The url parameter is optional, but especially
|
||||
// useful if the HTML fragment contains relative links
|
||||
void WriteHTML(const std::wstring& markup, const std::string& src_url) const;
|
||||
|
||||
// Adds a bookmark to the clipboard
|
||||
void WriteBookmark(const std::wstring& title, const std::string& url) const;
|
||||
|
||||
// Adds both a bookmark and an HTML hyperlink to the clipboard. It is a
|
||||
// convenience wrapper around WriteBookmark and WriteHTML.
|
||||
void WriteHyperlink(const std::wstring& title, const std::string& url) const;
|
||||
|
||||
// Adds a bitmap to the clipboard
|
||||
// This is the slowest way to copy a bitmap to the clipboard as we must first
|
||||
// memcpy the pixels into GDI and the blit the bitmap to the clipboard.
|
||||
// Pixel format is assumed to be 32-bit BI_RGB.
|
||||
void WriteBitmap(const void* pixels, const gfx::Size& size) const;
|
||||
|
||||
// Adds a bitmap to the clipboard
|
||||
// This function requires read and write access to the bitmap, but does not
|
||||
// actually modify the shared memory region.
|
||||
// Pixel format is assumed to be 32-bit BI_RGB.
|
||||
void WriteBitmapFromSharedMemory(const SharedMemory& bitmap,
|
||||
const gfx::Size& size) const;
|
||||
|
||||
// Adds a bitmap to the clipboard
|
||||
// This is the fastest way to copy a bitmap to the clipboard. The HBITMAP
|
||||
// may either be device-dependent or device-independent.
|
||||
void WriteBitmapFromHandle(HBITMAP hbitmap, const gfx::Size& size) const;
|
||||
|
||||
// Used by WebKit to determine whether WebKit wrote the clipboard last
|
||||
void WriteWebSmartPaste() const;
|
||||
|
||||
// Adds a file or group of files to the clipboard.
|
||||
void WriteFile(const std::wstring& file) const;
|
||||
void WriteFiles(const std::vector<std::wstring>& files) const;
|
||||
|
||||
// Tests whether the clipboard contains a certain format
|
||||
bool IsFormatAvailable(unsigned int format) const;
|
||||
|
||||
// Reads UNICODE text from the clipboard, if available.
|
||||
void ReadText(std::wstring* result) const;
|
||||
|
||||
// Reads ASCII text from the clipboard, if available.
|
||||
void ReadAsciiText(std::string* result) const;
|
||||
|
||||
// Reads HTML from the clipboard, if available.
|
||||
void ReadHTML(std::wstring* markup, std::string* src_url) const;
|
||||
|
||||
// Reads a bookmark from the clipboard, if available.
|
||||
void ReadBookmark(std::wstring* title, std::string* url) const;
|
||||
|
||||
// Reads a file or group of files from the clipboard, if available, into the
|
||||
// out paramter.
|
||||
void ReadFile(std::wstring* file) const;
|
||||
void ReadFiles(std::vector<std::wstring>* files) const;
|
||||
|
||||
private:
|
||||
static void MarkupToHTMLClipboardFormat(const std::wstring& markup,
|
||||
const std::string& src_url,
|
||||
std::string* html_fragment);
|
||||
|
||||
static void ParseHTMLClipboardFormat(const std::string& html_fragment,
|
||||
std::wstring* markup,
|
||||
std::string* src_url);
|
||||
|
||||
static void ParseBookmarkClipboardFormat(const std::wstring& bookmark,
|
||||
std::wstring* title,
|
||||
std::string* url);
|
||||
|
||||
HWND clipboard_owner_;
|
||||
|
||||
DISALLOW_EVIL_CONSTRUCTORS(Clipboard);
|
||||
};
|
||||
|
||||
#endif // BASE_CLIPBOARD_H__
|
211
base/clipboard_unittest.cc
Normal file
@ -0,0 +1,211 @@
|
||||
// Copyright 2008, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include "base/clipboard.h"
|
||||
#include "base/clipboard_util.h"
|
||||
#include "base/string_util.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
|
||||
namespace {
|
||||
class ClipboardTest : public testing::Test {
|
||||
};
|
||||
}
|
||||
|
||||
TEST(ClipboardTest, ClearTest) {
|
||||
Clipboard clipboard;
|
||||
|
||||
clipboard.Clear();
|
||||
EXPECT_EQ(false, clipboard.IsFormatAvailable(CF_TEXT));
|
||||
EXPECT_EQ(false, clipboard.IsFormatAvailable(
|
||||
ClipboardUtil::GetHtmlFormat()->cfFormat));
|
||||
}
|
||||
|
||||
TEST(ClipboardTest, TextTest) {
|
||||
Clipboard clipboard;
|
||||
|
||||
std::wstring text(L"This is a wstring!#$"), text_result;
|
||||
std::string ascii_text;
|
||||
|
||||
clipboard.Clear();
|
||||
clipboard.WriteText(text);
|
||||
EXPECT_EQ(true, clipboard.IsFormatAvailable(CF_UNICODETEXT));
|
||||
EXPECT_EQ(true, clipboard.IsFormatAvailable(CF_TEXT));
|
||||
clipboard.ReadText(&text_result);
|
||||
EXPECT_EQ(text, text_result);
|
||||
clipboard.ReadAsciiText(&ascii_text);
|
||||
EXPECT_EQ(WideToUTF8(text), ascii_text);
|
||||
}
|
||||
|
||||
TEST(ClipboardTest, HTMLTest) {
|
||||
Clipboard clipboard;
|
||||
|
||||
std::wstring markup(L"<strong>Hi!</string>"), markup_result;
|
||||
std::string url("http://www.example.com/"), url_result;
|
||||
|
||||
clipboard.Clear();
|
||||
clipboard.WriteHTML(markup, url);
|
||||
EXPECT_EQ(true, clipboard.IsFormatAvailable(
|
||||
ClipboardUtil::GetHtmlFormat()->cfFormat));
|
||||
clipboard.ReadHTML(&markup_result, &url_result);
|
||||
EXPECT_EQ(markup, markup_result);
|
||||
EXPECT_EQ(url, url_result);
|
||||
}
|
||||
|
||||
TEST(ClipboardTest, TrickyHTMLTest) {
|
||||
Clipboard clipboard;
|
||||
|
||||
std::wstring markup(L"<em>Bye!<!--EndFragment --></em>"), markup_result;
|
||||
std::string url, url_result;
|
||||
|
||||
clipboard.Clear();
|
||||
clipboard.WriteHTML(markup, url);
|
||||
EXPECT_EQ(true, clipboard.IsFormatAvailable(
|
||||
ClipboardUtil::GetHtmlFormat()->cfFormat));
|
||||
clipboard.ReadHTML(&markup_result, &url_result);
|
||||
EXPECT_EQ(markup, markup_result);
|
||||
EXPECT_EQ(url, url_result);
|
||||
}
|
||||
|
||||
TEST(ClipboardTest, BookmarkTest) {
|
||||
Clipboard clipboard;
|
||||
|
||||
std::wstring title(L"The Example Company"), title_result;
|
||||
std::string url("http://www.example.com/"), url_result;
|
||||
|
||||
clipboard.Clear();
|
||||
clipboard.WriteBookmark(title, url);
|
||||
EXPECT_EQ(true,
|
||||
clipboard.IsFormatAvailable(ClipboardUtil::GetUrlWFormat()->cfFormat));
|
||||
clipboard.ReadBookmark(&title_result, &url_result);
|
||||
EXPECT_EQ(title, title_result);
|
||||
EXPECT_EQ(url, url_result);
|
||||
}
|
||||
|
||||
TEST(ClipboardTest, HyperlinkTest) {
|
||||
Clipboard clipboard;
|
||||
|
||||
std::wstring title(L"The Example Company"), title_result;
|
||||
std::string url("http://www.example.com/"), url_result;
|
||||
std::wstring html(L"<a href=\"http://www.example.com/\">"
|
||||
L"The Example Company</a>"), html_result;
|
||||
|
||||
clipboard.Clear();
|
||||
clipboard.WriteHyperlink(title, url);
|
||||
EXPECT_EQ(true,
|
||||
clipboard.IsFormatAvailable(ClipboardUtil::GetUrlWFormat()->cfFormat));
|
||||
EXPECT_EQ(true,
|
||||
clipboard.IsFormatAvailable(ClipboardUtil::GetHtmlFormat()->cfFormat));
|
||||
clipboard.ReadBookmark(&title_result, &url_result);
|
||||
EXPECT_EQ(title, title_result);
|
||||
EXPECT_EQ(url, url_result);
|
||||
clipboard.ReadHTML(&html_result, &url_result);
|
||||
EXPECT_EQ(html, html_result);
|
||||
//XXX EXPECT_FALSE(url_result.is_valid());
|
||||
}
|
||||
|
||||
TEST(ClipboardTest, MultiFormatTest) {
|
||||
Clipboard clipboard;
|
||||
|
||||
std::wstring text(L"Hi!"), text_result;
|
||||
std::wstring markup(L"<strong>Hi!</string>"), markup_result;
|
||||
std::string url("http://www.example.com/"), url_result;
|
||||
std::string ascii_text;
|
||||
|
||||
clipboard.Clear();
|
||||
clipboard.WriteHTML(markup, url);
|
||||
clipboard.WriteText(text);
|
||||
EXPECT_EQ(true,
|
||||
clipboard.IsFormatAvailable(ClipboardUtil::GetHtmlFormat()->cfFormat));
|
||||
EXPECT_EQ(true, clipboard.IsFormatAvailable(CF_UNICODETEXT));
|
||||
EXPECT_EQ(true, clipboard.IsFormatAvailable(CF_TEXT));
|
||||
clipboard.ReadHTML(&markup_result, &url_result);
|
||||
EXPECT_EQ(markup, markup_result);
|
||||
EXPECT_EQ(url, url_result);
|
||||
clipboard.ReadText(&text_result);
|
||||
EXPECT_EQ(text, text_result);
|
||||
clipboard.ReadAsciiText(&ascii_text);
|
||||
EXPECT_EQ(WideToUTF8(text), ascii_text);
|
||||
}
|
||||
|
||||
TEST(ClipboardTest, WebSmartPasteTest) {
|
||||
Clipboard clipboard;
|
||||
|
||||
clipboard.Clear();
|
||||
clipboard.WriteWebSmartPaste();
|
||||
EXPECT_EQ(true, clipboard.IsFormatAvailable(
|
||||
ClipboardUtil::GetWebKitSmartPasteFormat()->cfFormat));
|
||||
}
|
||||
|
||||
TEST(ClipboardTest, BitmapTest) {
|
||||
unsigned int fake_bitmap[] = {
|
||||
0x46155189, 0xF6A55C8D, 0x79845674, 0xFA57BD89,
|
||||
0x78FD46AE, 0x87C64F5A, 0x36EDC5AF, 0x4378F568,
|
||||
0x91E9F63A, 0xC31EA14F, 0x69AB32DF, 0x643A3FD1,
|
||||
};
|
||||
|
||||
Clipboard clipboard;
|
||||
|
||||
clipboard.Clear();
|
||||
clipboard.WriteBitmap(fake_bitmap, gfx::Size(3, 4));
|
||||
EXPECT_EQ(true, clipboard.IsFormatAvailable(CF_BITMAP));
|
||||
}
|
||||
|
||||
// Files for this test don't actually need to exist on the file system, just
|
||||
// don't try to use a non-existent file you've retrieved from the clipboard.
|
||||
TEST(ClipboardTest, FileTest) {
|
||||
Clipboard clipboard;
|
||||
clipboard.Clear();
|
||||
|
||||
std::wstring file = L"C:\\Downloads\\My Downloads\\A Special File.txt";
|
||||
clipboard.WriteFile(file);
|
||||
std::wstring out_file;
|
||||
clipboard.ReadFile(&out_file);
|
||||
EXPECT_EQ(file, out_file);
|
||||
}
|
||||
|
||||
TEST(ClipboardTest, MultipleFilesTest) {
|
||||
Clipboard clipboard;
|
||||
clipboard.Clear();
|
||||
|
||||
std::vector<std::wstring> files;
|
||||
files.push_back(L"C:\\Downloads\\My Downloads\\File 1.exe");
|
||||
files.push_back(L"C:\\Downloads\\My Downloads\\File 2.pdf");
|
||||
files.push_back(L"C:\\Downloads\\My Downloads\\File 3.doc");
|
||||
clipboard.WriteFiles(files);
|
||||
|
||||
std::vector<std::wstring> out_files;
|
||||
clipboard.ReadFiles(&out_files);
|
||||
|
||||
EXPECT_EQ(files.size(), out_files.size());
|
||||
for (size_t i = 0; i < out_files.size(); ++i)
|
||||
EXPECT_EQ(files[i], out_files[i]);
|
||||
}
|
400
base/clipboard_util.cc
Normal file
@ -0,0 +1,400 @@
|
||||
// Copyright 2008, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include "base/clipboard_util.h"
|
||||
|
||||
#include <shellapi.h>
|
||||
#include <shlwapi.h>
|
||||
#include <wininet.h>
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/scoped_handle.h"
|
||||
#include "base/string_util.h"
|
||||
|
||||
namespace {
|
||||
|
||||
bool GetUrlFromHDrop(IDataObject* data_object, std::wstring* url,
|
||||
std::wstring* title) {
|
||||
DCHECK(data_object && url && title);
|
||||
|
||||
STGMEDIUM medium;
|
||||
if (FAILED(data_object->GetData(ClipboardUtil::GetCFHDropFormat(), &medium)))
|
||||
return false;
|
||||
|
||||
HDROP hdrop = static_cast<HDROP>(GlobalLock(medium.hGlobal));
|
||||
|
||||
if (!hdrop)
|
||||
return false;
|
||||
|
||||
bool success = false;
|
||||
wchar_t filename[MAX_PATH];
|
||||
if (DragQueryFileW(hdrop, 0, filename, arraysize(filename))) {
|
||||
wchar_t url_buffer[INTERNET_MAX_URL_LENGTH];
|
||||
if (0 == _wcsicmp(PathFindExtensionW(filename), L".url") &&
|
||||
GetPrivateProfileStringW(L"InternetShortcut", L"url", 0, url_buffer,
|
||||
arraysize(url_buffer), filename)) {
|
||||
*url = url_buffer;
|
||||
PathRemoveExtension(filename);
|
||||
title->assign(PathFindFileName(filename));
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
|
||||
DragFinish(hdrop);
|
||||
GlobalUnlock(medium.hGlobal);
|
||||
// We don't need to call ReleaseStgMedium here because as far as I can tell,
|
||||
// DragFinish frees the hGlobal for us.
|
||||
return success;
|
||||
}
|
||||
|
||||
bool SplitUrlAndTitle(const std::wstring& str, std::wstring* url,
|
||||
std::wstring* title) {
|
||||
DCHECK(url && title);
|
||||
size_t newline_pos = str.find('\n');
|
||||
bool success = false;
|
||||
if (newline_pos != std::string::npos) {
|
||||
*url = str.substr(0, newline_pos);
|
||||
title->assign(str.substr(newline_pos + 1));
|
||||
success = true;
|
||||
} else {
|
||||
*url = str;
|
||||
title->assign(str);
|
||||
success = true;
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
FORMATETC* ClipboardUtil::GetUrlFormat() {
|
||||
static UINT cf = RegisterClipboardFormat(CFSTR_INETURLA);
|
||||
static FORMATETC format = {cf, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
|
||||
return &format;
|
||||
}
|
||||
|
||||
FORMATETC* ClipboardUtil::GetUrlWFormat() {
|
||||
static UINT cf = RegisterClipboardFormat(CFSTR_INETURLW);
|
||||
static FORMATETC format = {cf, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
|
||||
return &format;
|
||||
}
|
||||
|
||||
FORMATETC* ClipboardUtil::GetMozUrlFormat() {
|
||||
// The format is "URL\nTitle"
|
||||
static UINT cf = RegisterClipboardFormat(L"text/x-moz-url");
|
||||
static FORMATETC format = {cf, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
|
||||
return &format;
|
||||
}
|
||||
|
||||
FORMATETC* ClipboardUtil::GetPlainTextFormat() {
|
||||
// We don't need to register this format since it's a built in format.
|
||||
static FORMATETC format = {CF_TEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
|
||||
return &format;
|
||||
}
|
||||
|
||||
FORMATETC* ClipboardUtil::GetPlainTextWFormat() {
|
||||
// We don't need to register this format since it's a built in format.
|
||||
static FORMATETC format = {CF_UNICODETEXT, 0, DVASPECT_CONTENT, -1,
|
||||
TYMED_HGLOBAL};
|
||||
return &format;
|
||||
}
|
||||
|
||||
FORMATETC* ClipboardUtil::GetFilenameWFormat() {
|
||||
static UINT cf = RegisterClipboardFormat(CFSTR_FILENAMEW);
|
||||
static FORMATETC format = {cf, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
|
||||
return &format;
|
||||
}
|
||||
|
||||
FORMATETC* ClipboardUtil::GetFilenameFormat()
|
||||
{
|
||||
static UINT cf = RegisterClipboardFormat(CFSTR_FILENAMEA);
|
||||
static FORMATETC format = {cf, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
|
||||
return &format;
|
||||
}
|
||||
|
||||
FORMATETC* ClipboardUtil::GetHtmlFormat() {
|
||||
static UINT cf = RegisterClipboardFormat(L"HTML Format");
|
||||
static FORMATETC format = {cf, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
|
||||
return &format;
|
||||
}
|
||||
|
||||
FORMATETC* ClipboardUtil::GetTextHtmlFormat() {
|
||||
static UINT cf = RegisterClipboardFormat(L"text/html");
|
||||
static FORMATETC format = {cf, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
|
||||
return &format;
|
||||
}
|
||||
|
||||
FORMATETC* ClipboardUtil::GetCFHDropFormat() {
|
||||
// We don't need to register this format since it's a built in format.
|
||||
static FORMATETC format = {CF_HDROP, 0, DVASPECT_CONTENT, -1,
|
||||
TYMED_HGLOBAL};
|
||||
return &format;
|
||||
}
|
||||
|
||||
FORMATETC* ClipboardUtil::GetFileDescriptorFormat() {
|
||||
static UINT cf = RegisterClipboardFormat(CFSTR_FILEDESCRIPTOR);
|
||||
static FORMATETC format = {cf, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
|
||||
return &format;
|
||||
}
|
||||
|
||||
FORMATETC* ClipboardUtil::GetFileContentFormatZero() {
|
||||
static UINT cf = RegisterClipboardFormat(CFSTR_FILECONTENTS);
|
||||
static FORMATETC format = {cf, 0, DVASPECT_CONTENT, 0, TYMED_HGLOBAL};
|
||||
return &format;
|
||||
}
|
||||
|
||||
FORMATETC* ClipboardUtil::GetWebKitSmartPasteFormat() {
|
||||
static UINT cf = RegisterClipboardFormat(L"WebKit Smart Paste Format");
|
||||
static FORMATETC format = {cf, 0, DVASPECT_CONTENT, 0, TYMED_HGLOBAL};
|
||||
return &format;
|
||||
}
|
||||
|
||||
|
||||
bool ClipboardUtil::HasUrl(IDataObject* data_object) {
|
||||
DCHECK(data_object);
|
||||
return SUCCEEDED(data_object->QueryGetData(GetMozUrlFormat())) ||
|
||||
SUCCEEDED(data_object->QueryGetData(GetUrlWFormat())) ||
|
||||
SUCCEEDED(data_object->QueryGetData(GetUrlFormat())) ||
|
||||
SUCCEEDED(data_object->QueryGetData(GetFilenameWFormat())) ||
|
||||
SUCCEEDED(data_object->QueryGetData(GetFilenameFormat()));
|
||||
}
|
||||
|
||||
bool ClipboardUtil::HasFilenames(IDataObject* data_object) {
|
||||
DCHECK(data_object);
|
||||
return SUCCEEDED(data_object->QueryGetData(GetCFHDropFormat()));
|
||||
}
|
||||
|
||||
bool ClipboardUtil::HasPlainText(IDataObject* data_object) {
|
||||
DCHECK(data_object);
|
||||
return SUCCEEDED(data_object->QueryGetData(GetPlainTextWFormat())) ||
|
||||
SUCCEEDED(data_object->QueryGetData(GetPlainTextFormat()));
|
||||
}
|
||||
|
||||
|
||||
bool ClipboardUtil::GetUrl(IDataObject* data_object,
|
||||
std::wstring* url, std::wstring* title) {
|
||||
DCHECK(data_object && url && title);
|
||||
if (!HasUrl(data_object))
|
||||
return false;
|
||||
|
||||
// Try to extract a URL from |data_object| in a variety of formats.
|
||||
STGMEDIUM store;
|
||||
if (GetUrlFromHDrop(data_object, url, title)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (SUCCEEDED(data_object->GetData(GetMozUrlFormat(), &store)) ||
|
||||
SUCCEEDED(data_object->GetData(GetUrlWFormat(), &store))) {
|
||||
// Mozilla URL format or unicode URL
|
||||
ScopedHGlobal<wchar_t> data(store.hGlobal);
|
||||
bool success = SplitUrlAndTitle(data.get(), url, title);
|
||||
ReleaseStgMedium(&store);
|
||||
if (success)
|
||||
return true;
|
||||
}
|
||||
|
||||
if (SUCCEEDED(data_object->GetData(GetUrlFormat(), &store))) {
|
||||
// URL using ascii
|
||||
ScopedHGlobal<char> data(store.hGlobal);
|
||||
bool success = SplitUrlAndTitle(UTF8ToWide(data.get()), url, title);
|
||||
ReleaseStgMedium(&store);
|
||||
if (success)
|
||||
return true;
|
||||
}
|
||||
|
||||
if (SUCCEEDED(data_object->GetData(GetFilenameWFormat(), &store))) {
|
||||
// filename using unicode
|
||||
ScopedHGlobal<wchar_t> data(store.hGlobal);
|
||||
bool success = false;
|
||||
if (data.get() && data.get()[0] && (PathFileExists(data.get()) ||
|
||||
PathIsUNC(data.get()))) {
|
||||
wchar_t file_url[INTERNET_MAX_URL_LENGTH];
|
||||
DWORD file_url_len = sizeof(file_url) / sizeof(file_url[0]);
|
||||
if (SUCCEEDED(::UrlCreateFromPathW(data.get(), file_url, &file_url_len,
|
||||
0))) {
|
||||
*url = file_url;
|
||||
title->assign(file_url);
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
ReleaseStgMedium(&store);
|
||||
if (success)
|
||||
return true;
|
||||
}
|
||||
|
||||
if (SUCCEEDED(data_object->GetData(GetFilenameFormat(), &store))) {
|
||||
// filename using ascii
|
||||
ScopedHGlobal<char> data(store.hGlobal);
|
||||
bool success = false;
|
||||
if (data.get() && data.get()[0] && (PathFileExistsA(data.get()) ||
|
||||
PathIsUNCA(data.get()))) {
|
||||
char file_url[INTERNET_MAX_URL_LENGTH];
|
||||
DWORD file_url_len = sizeof(file_url) / sizeof(file_url[0]);
|
||||
if (SUCCEEDED(::UrlCreateFromPathA(data.get(), file_url, &file_url_len, 0))) {
|
||||
*url = UTF8ToWide(file_url);
|
||||
title->assign(*url);
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
ReleaseStgMedium(&store);
|
||||
if (success)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ClipboardUtil::GetFilenames(IDataObject* data_object,
|
||||
std::vector<std::wstring>* filenames) {
|
||||
DCHECK(data_object && filenames);
|
||||
if (!HasFilenames(data_object))
|
||||
return false;
|
||||
|
||||
STGMEDIUM medium;
|
||||
if (FAILED(data_object->GetData(GetCFHDropFormat(), &medium)))
|
||||
return false;
|
||||
|
||||
HDROP hdrop = static_cast<HDROP>(GlobalLock(medium.hGlobal));
|
||||
if (!hdrop)
|
||||
return false;
|
||||
|
||||
const int kMaxFilenameLen = 4096;
|
||||
const unsigned num_files = DragQueryFileW(hdrop, 0xffffffff, 0, 0);
|
||||
for (unsigned int i = 0; i < num_files; ++i) {
|
||||
wchar_t filename[kMaxFilenameLen];
|
||||
if (!DragQueryFileW(hdrop, i, filename, kMaxFilenameLen))
|
||||
continue;
|
||||
filenames->push_back(filename);
|
||||
}
|
||||
|
||||
DragFinish(hdrop);
|
||||
GlobalUnlock(medium.hGlobal);
|
||||
// We don't need to call ReleaseStgMedium here because as far as I can tell,
|
||||
// DragFinish frees the hGlobal for us.
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ClipboardUtil::GetPlainText(IDataObject* data_object,
|
||||
std::wstring* plain_text) {
|
||||
DCHECK(data_object && plain_text);
|
||||
if (!HasPlainText(data_object))
|
||||
return false;
|
||||
|
||||
STGMEDIUM store;
|
||||
bool success = false;
|
||||
if (SUCCEEDED(data_object->GetData(GetPlainTextWFormat(), &store))) {
|
||||
// Unicode text
|
||||
ScopedHGlobal<wchar_t> data(store.hGlobal);
|
||||
plain_text->assign(data.get());
|
||||
ReleaseStgMedium(&store);
|
||||
success = true;
|
||||
} else if (SUCCEEDED(data_object->GetData(GetPlainTextFormat(), &store))) {
|
||||
// ascii text
|
||||
ScopedHGlobal<char> data(store.hGlobal);
|
||||
plain_text->assign(UTF8ToWide(data.get()));
|
||||
ReleaseStgMedium(&store);
|
||||
success = true;
|
||||
} else {
|
||||
//If a file is dropped on the window, it does not provide either of the
|
||||
//plain text formats, so here we try to forcibly get a url.
|
||||
std::wstring title;
|
||||
success = GetUrl(data_object, plain_text, &title);
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
bool ClipboardUtil::GetCFHtml(IDataObject* data_object,
|
||||
std::wstring* cf_html) {
|
||||
DCHECK(data_object && cf_html);
|
||||
if (FAILED(data_object->QueryGetData(GetHtmlFormat())))
|
||||
return false;
|
||||
|
||||
STGMEDIUM store;
|
||||
if (FAILED(data_object->GetData(GetHtmlFormat(), &store)))
|
||||
return false;
|
||||
|
||||
// MS CF html
|
||||
ScopedHGlobal<char> data(store.hGlobal);
|
||||
cf_html->assign(UTF8ToWide(std::string(data.get(), data.Size())));
|
||||
ReleaseStgMedium(&store);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ClipboardUtil::GetTextHtml(IDataObject* data_object,
|
||||
std::wstring* text_html) {
|
||||
DCHECK(data_object && text_html);
|
||||
if (FAILED(data_object->QueryGetData(GetTextHtmlFormat())))
|
||||
return false;
|
||||
|
||||
STGMEDIUM store;
|
||||
if (FAILED(data_object->GetData(GetTextHtmlFormat(), &store)))
|
||||
return false;
|
||||
|
||||
// raw html
|
||||
ScopedHGlobal<wchar_t> data(store.hGlobal);
|
||||
text_html->assign(data.get());
|
||||
ReleaseStgMedium(&store);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ClipboardUtil::GetFileContents(IDataObject* data_object,
|
||||
std::wstring* filename, std::string* file_contents) {
|
||||
DCHECK(data_object && filename && file_contents);
|
||||
bool has_data =
|
||||
SUCCEEDED(data_object->QueryGetData(GetFileContentFormatZero())) ||
|
||||
SUCCEEDED(data_object->QueryGetData(GetFileDescriptorFormat()));
|
||||
|
||||
if (!has_data)
|
||||
return false;
|
||||
|
||||
STGMEDIUM content;
|
||||
// The call to GetData can be very slow depending on what is in
|
||||
// |data_object|.
|
||||
if (SUCCEEDED(data_object->GetData(GetFileContentFormatZero(), &content))) {
|
||||
if (TYMED_HGLOBAL == content.tymed) {
|
||||
ScopedHGlobal<char> data(content.hGlobal);
|
||||
// The size includes the trailing NULL byte. We don't want it.
|
||||
file_contents->assign(data.get(), data.Size() - 1);
|
||||
}
|
||||
ReleaseStgMedium(&content);
|
||||
}
|
||||
|
||||
STGMEDIUM description;
|
||||
if (SUCCEEDED(data_object->GetData(GetFileDescriptorFormat(),
|
||||
&description))) {
|
||||
ScopedHGlobal<FILEGROUPDESCRIPTOR> fgd(description.hGlobal);
|
||||
// We expect there to be at least one file in here.
|
||||
DCHECK(fgd->cItems >= 1);
|
||||
filename->assign(fgd->fgd[0].cFileName);
|
||||
ReleaseStgMedium(&description);
|
||||
}
|
||||
return true;
|
||||
}
|
76
base/clipboard_util.h
Normal file
@ -0,0 +1,76 @@
|
||||
// Copyright 2008, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Some helper functions for working with the clipboard and IDataObjects.
|
||||
|
||||
#include <shlobj.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
class ClipboardUtil {
|
||||
public:
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Clipboard formats.
|
||||
static FORMATETC* GetUrlFormat();
|
||||
static FORMATETC* GetUrlWFormat();
|
||||
static FORMATETC* GetMozUrlFormat();
|
||||
static FORMATETC* GetPlainTextFormat();
|
||||
static FORMATETC* GetPlainTextWFormat();
|
||||
static FORMATETC* GetFilenameFormat();
|
||||
static FORMATETC* GetFilenameWFormat();
|
||||
// MS HTML Format
|
||||
static FORMATETC* GetHtmlFormat();
|
||||
// Firefox text/html
|
||||
static FORMATETC* GetTextHtmlFormat();
|
||||
static FORMATETC* GetCFHDropFormat();
|
||||
static FORMATETC* GetFileDescriptorFormat();
|
||||
static FORMATETC* GetFileContentFormatZero();
|
||||
static FORMATETC* GetWebKitSmartPasteFormat();
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// These methods check to see if |data_object| has the requested type.
|
||||
// Returns true if it does.
|
||||
static bool HasUrl(IDataObject* data_object);
|
||||
static bool HasFilenames(IDataObject* data_object);
|
||||
static bool HasPlainText(IDataObject* data_object);
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Helper methods to extract information from an IDataObject. These methods
|
||||
// return true if the requested data type is found in |data_object|.
|
||||
static bool GetUrl(IDataObject* data_object,
|
||||
std::wstring* url, std::wstring* title);
|
||||
static bool GetFilenames(IDataObject* data_object,
|
||||
std::vector<std::wstring>* filenames);
|
||||
static bool GetPlainText(IDataObject* data_object, std::wstring* plain_text);
|
||||
static bool GetCFHtml(IDataObject* data_object, std::wstring* cf_html);
|
||||
static bool GetTextHtml(IDataObject* data_object, std::wstring* text_html);
|
||||
static bool GetFileContents(IDataObject* data_object,
|
||||
std::wstring* filename,
|
||||
std::string* file_contents);
|
||||
};
|
246
base/command_line.cc
Normal file
@ -0,0 +1,246 @@
|
||||
// Copyright 2008, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include <windows.h>
|
||||
#include <shellapi.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "base/command_line.h"
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "base/singleton.h"
|
||||
#include "base/string_util.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
// Since we use a lazy match, make sure that longer versions (like L"--")
|
||||
// are listed before shorter versions (like L"-") of similar prefixes.
|
||||
const wchar_t* const CommandLine::kSwitchPrefixes[] = {L"--", L"-", L"/"};
|
||||
|
||||
const wchar_t CommandLine::kSwitchValueSeparator[] = L"=";
|
||||
|
||||
static void Lowercase(wstring* parameter) {
|
||||
transform(parameter->begin(), parameter->end(), parameter->begin(), tolower);
|
||||
}
|
||||
|
||||
// CommandLine::Data
|
||||
//
|
||||
// This object holds the parsed data for a command line. We hold this in a
|
||||
// separate object from |CommandLine| so that we can share the parsed data
|
||||
// across multiple |CommandLine| objects. When we share |Data|, we might be
|
||||
// accessing this object on multiple threads. To ensure thread safety, the
|
||||
// public interface of this object is const only.
|
||||
//
|
||||
// Do NOT add any non-const methods to this object. You have been warned.
|
||||
class CommandLine::Data {
|
||||
public:
|
||||
Data() {
|
||||
Init(GetCommandLineW());
|
||||
}
|
||||
|
||||
Data(const wstring& command_line) {
|
||||
Init(command_line);
|
||||
}
|
||||
|
||||
const std::wstring& command_line_string() const {
|
||||
return command_line_string_;
|
||||
}
|
||||
|
||||
const std::wstring& program() const {
|
||||
return program_;
|
||||
}
|
||||
|
||||
const std::map<std::wstring, std::wstring>& switches() const {
|
||||
return switches_;
|
||||
}
|
||||
|
||||
const std::vector<std::wstring>& loose_values() const {
|
||||
return loose_values_;
|
||||
}
|
||||
|
||||
private:
|
||||
// Returns true if parameter_string represents a switch. If true,
|
||||
// switch_string and switch_value are set. (If false, both are
|
||||
// set to the empty string.)
|
||||
static bool IsSwitch(const wstring& parameter_string,
|
||||
wstring* switch_string,
|
||||
wstring* switch_value) {
|
||||
|
||||
*switch_string = L"";
|
||||
*switch_value = L"";
|
||||
|
||||
for (size_t i = 0; i < arraysize(kSwitchPrefixes); ++i) {
|
||||
std::wstring prefix(kSwitchPrefixes[i]);
|
||||
if (parameter_string.find(prefix) != 0) // check prefix
|
||||
continue;
|
||||
|
||||
const size_t switch_start = prefix.length();
|
||||
const size_t equals_position = parameter_string.find(
|
||||
kSwitchValueSeparator, switch_start);
|
||||
if (equals_position == wstring::npos) {
|
||||
*switch_string = parameter_string.substr(switch_start);
|
||||
} else {
|
||||
*switch_string = parameter_string.substr(
|
||||
switch_start, equals_position - switch_start);
|
||||
*switch_value = parameter_string.substr(equals_position + 1);
|
||||
}
|
||||
Lowercase(switch_string);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Does the actual parsing of the command line.
|
||||
void Init(const std::wstring& command_line) {
|
||||
TrimWhitespace(command_line, TRIM_ALL, &command_line_string_);
|
||||
|
||||
if (command_line_string_.empty())
|
||||
return;
|
||||
|
||||
int num_args = 0;
|
||||
wchar_t** args = NULL;
|
||||
|
||||
args = CommandLineToArgvW(command_line_string_.c_str(), &num_args);
|
||||
|
||||
// Populate program_ with the trimmed version of the first arg.
|
||||
TrimWhitespace(args[0], TRIM_ALL, &program_);
|
||||
|
||||
for (int i = 1; i < num_args; ++i) {
|
||||
wstring arg;
|
||||
TrimWhitespace(args[i], TRIM_ALL, &arg);
|
||||
|
||||
wstring switch_string;
|
||||
wstring switch_value;
|
||||
if (IsSwitch(arg, &switch_string, &switch_value)) {
|
||||
switches_[switch_string] = switch_value;
|
||||
} else {
|
||||
loose_values_.push_back(arg);
|
||||
}
|
||||
}
|
||||
|
||||
if (args)
|
||||
LocalFree(args);
|
||||
}
|
||||
|
||||
std::wstring command_line_string_;
|
||||
std::wstring program_;
|
||||
std::map<std::wstring, std::wstring> switches_;
|
||||
std::vector<std::wstring> loose_values_;
|
||||
|
||||
DISALLOW_EVIL_CONSTRUCTORS(CommandLine::Data);
|
||||
};
|
||||
|
||||
CommandLine::CommandLine()
|
||||
: we_own_data_(false), // The Singleton class will manage it for us.
|
||||
data_(Singleton<Data>::get()) {
|
||||
}
|
||||
|
||||
CommandLine::CommandLine(const wstring& command_line)
|
||||
: we_own_data_(true),
|
||||
data_(new Data(command_line)) {
|
||||
}
|
||||
|
||||
CommandLine::~CommandLine() {
|
||||
if (we_own_data_)
|
||||
delete data_;
|
||||
}
|
||||
|
||||
bool CommandLine::HasSwitch(const wstring& switch_string) const {
|
||||
wstring lowercased_switch(switch_string);
|
||||
Lowercase(&lowercased_switch);
|
||||
return data_->switches().find(lowercased_switch) != data_->switches().end();
|
||||
}
|
||||
|
||||
wstring CommandLine::GetSwitchValue(const wstring& switch_string) const {
|
||||
wstring lowercased_switch(switch_string);
|
||||
Lowercase(&lowercased_switch);
|
||||
|
||||
const map<wstring, wstring>::const_iterator result =
|
||||
data_->switches().find(lowercased_switch);
|
||||
|
||||
if (result == data_->switches().end()) {
|
||||
return L"";
|
||||
} else {
|
||||
return result->second;
|
||||
}
|
||||
}
|
||||
|
||||
size_t CommandLine::GetLooseValueCount() const {
|
||||
return data_->loose_values().size();
|
||||
}
|
||||
|
||||
CommandLine::LooseValueIterator CommandLine::GetLooseValuesBegin() const {
|
||||
return data_->loose_values().begin();
|
||||
}
|
||||
|
||||
CommandLine::LooseValueIterator CommandLine::GetLooseValuesEnd() const {
|
||||
return data_->loose_values().end();
|
||||
}
|
||||
|
||||
std::wstring CommandLine::command_line_string() const {
|
||||
return data_->command_line_string();
|
||||
}
|
||||
|
||||
std::wstring CommandLine::program() const {
|
||||
return data_->program();
|
||||
}
|
||||
|
||||
// static
|
||||
void CommandLine::AppendSwitch(wstring* command_line_string,
|
||||
const wstring& switch_string) {
|
||||
DCHECK(command_line_string);
|
||||
command_line_string->append(L" ");
|
||||
command_line_string->append(kSwitchPrefixes[0]);
|
||||
command_line_string->append(switch_string);
|
||||
}
|
||||
|
||||
// static
|
||||
void CommandLine::AppendSwitchWithValue(wstring* command_line_string,
|
||||
const wstring& switch_string,
|
||||
const wstring& value_string) {
|
||||
AppendSwitch(command_line_string, switch_string);
|
||||
|
||||
if (value_string.empty())
|
||||
return;
|
||||
|
||||
command_line_string->append(kSwitchValueSeparator);
|
||||
// NOTE(jhughes): If the value contains a quotation mark at one
|
||||
// end but not both, you may get unusable output.
|
||||
if ((value_string.find(L" ") != std::wstring::npos) &&
|
||||
(value_string[0] != L'"') &&
|
||||
(value_string[value_string.length() - 1] != L'"')) {
|
||||
// need to provide quotes
|
||||
StringAppendF(command_line_string, L"\"%s\"", value_string.c_str());
|
||||
} else {
|
||||
command_line_string->append(value_string);
|
||||
}
|
||||
}
|
119
base/command_line.h
Normal file
@ -0,0 +1,119 @@
|
||||
// Copyright 2008, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// This file contains a class that can be used to extract the salient
|
||||
// elements of a command line in a relatively lightweight manner.
|
||||
// Switches can optionally have a value attached using an equals sign,
|
||||
// as in "-switch=value". Arguments that aren't prefixed with a
|
||||
// switch prefix are considered "loose parameters". Switch names
|
||||
// are case-insensitive.
|
||||
|
||||
#ifndef BASE_COMMAND_LINE_H__
|
||||
#define BASE_COMMAND_LINE_H__
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include "base/scoped_ptr.h"
|
||||
|
||||
class CommandLine {
|
||||
public:
|
||||
// Creates a parsed version of the command line used to launch
|
||||
// the current process.
|
||||
CommandLine();
|
||||
|
||||
// Creates a parsed version of the given command-line string.
|
||||
// The program name is assumed to be the first item in the string.
|
||||
CommandLine(const std::wstring& command_line);
|
||||
|
||||
~CommandLine();
|
||||
|
||||
// Returns true if this command line contains the given switch.
|
||||
// (Switch names are case-insensitive.)
|
||||
bool HasSwitch(const std::wstring& switch_string) const;
|
||||
|
||||
// Returns the value associated with the given switch. If the
|
||||
// switch has no value or isn't present, this method returns
|
||||
// the empty string.
|
||||
std::wstring GetSwitchValue(const std::wstring& switch_string) const;
|
||||
|
||||
// Returns the number of "loose values" found in the command line.
|
||||
// Loose values are arguments that aren't switches.
|
||||
// (The program name is also excluded from the set of loose values.)
|
||||
size_t GetLooseValueCount() const;
|
||||
|
||||
typedef std::vector<std::wstring>::const_iterator LooseValueIterator;
|
||||
|
||||
// Returns a const_iterator to the list of loose values.
|
||||
LooseValueIterator GetLooseValuesBegin() const;
|
||||
|
||||
// Returns the end const_iterator for the list of loose values.
|
||||
LooseValueIterator GetLooseValuesEnd() const;
|
||||
|
||||
// Simply returns the original command line string.
|
||||
std::wstring command_line_string() const;
|
||||
|
||||
// Returns the program part of the command line string (the first item).
|
||||
std::wstring program() const;
|
||||
|
||||
// An array containing the prefixes that identify an argument as
|
||||
// a switch.
|
||||
static const wchar_t* const kSwitchPrefixes[];
|
||||
|
||||
// The string that's used to separate switches from their values.
|
||||
static const wchar_t kSwitchValueSeparator[];
|
||||
|
||||
// Appends the given switch string (preceded by a space and a switch
|
||||
// prefix) to the given string.
|
||||
static void AppendSwitch(std::wstring* command_line_string,
|
||||
const std::wstring& switch_string);
|
||||
|
||||
// Appends the given switch string (preceded by a space and a switch
|
||||
// prefix) to the given string, with the given value attached.
|
||||
static void AppendSwitchWithValue(std::wstring* command_line_string,
|
||||
const std::wstring& switch_string,
|
||||
const std::wstring& value_string);
|
||||
|
||||
private:
|
||||
class Data;
|
||||
|
||||
// True if we are responsible for deleting our |data_| pointer. In some cases
|
||||
// we cache the result of parsing the command line and |data_|'s lifetime is
|
||||
// managed by someone else (e.g., the |Singleton| class).
|
||||
bool we_own_data_;
|
||||
|
||||
// A pointer to the parsed version of the command line.
|
||||
Data* data_;
|
||||
|
||||
DISALLOW_EVIL_CONSTRUCTORS(CommandLine);
|
||||
};
|
||||
|
||||
#endif // BASE_COMMAND_LINE_H__
|
125
base/command_line_unittest.cc
Normal file
@ -0,0 +1,125 @@
|
||||
// Copyright 2008, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "base/command_line.h"
|
||||
#include "base/logging.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
|
||||
namespace {
|
||||
class CommandLineTest : public testing::Test {
|
||||
};
|
||||
};
|
||||
|
||||
TEST(CommandLineTest, CommandLineConstructor) {
|
||||
CommandLine cl(L"program --foo= -bAr /Spaetzel=pierogi /Baz flim "
|
||||
L"--other-switches=\"--dog=canine --cat=feline\" "
|
||||
L"-spaetzle=Crepe -=loosevalue flan "
|
||||
L"--input-translation=\"45\"--output-rotation "
|
||||
L"\"in the time of submarines...\"");
|
||||
|
||||
EXPECT_FALSE(cl.command_line_string().empty());
|
||||
EXPECT_FALSE(cl.HasSwitch(L"cruller"));
|
||||
EXPECT_FALSE(cl.HasSwitch(L"flim"));
|
||||
EXPECT_FALSE(cl.HasSwitch(L"program"));
|
||||
EXPECT_FALSE(cl.HasSwitch(L"dog"));
|
||||
EXPECT_FALSE(cl.HasSwitch(L"cat"));
|
||||
EXPECT_FALSE(cl.HasSwitch(L"output-rotation"));
|
||||
|
||||
EXPECT_EQ(L"program", cl.program());
|
||||
|
||||
EXPECT_TRUE(cl.HasSwitch(L"foo"));
|
||||
EXPECT_TRUE(cl.HasSwitch(L"bar"));
|
||||
EXPECT_TRUE(cl.HasSwitch(L"baz"));
|
||||
EXPECT_TRUE(cl.HasSwitch(L"spaetzle"));
|
||||
EXPECT_TRUE(cl.HasSwitch(L"SPAETZLE"));
|
||||
EXPECT_TRUE(cl.HasSwitch(L"other-switches"));
|
||||
EXPECT_TRUE(cl.HasSwitch(L"input-translation"));
|
||||
|
||||
EXPECT_EQ(L"Crepe", cl.GetSwitchValue(L"spaetzle"));
|
||||
EXPECT_EQ(L"", cl.GetSwitchValue(L"Foo"));
|
||||
EXPECT_EQ(L"", cl.GetSwitchValue(L"bar"));
|
||||
EXPECT_EQ(L"", cl.GetSwitchValue(L"cruller"));
|
||||
EXPECT_EQ(L"--dog=canine --cat=feline", cl.GetSwitchValue(L"other-switches"));
|
||||
EXPECT_EQ(L"45--output-rotation", cl.GetSwitchValue(L"input-translation"));
|
||||
|
||||
EXPECT_EQ(3, cl.GetLooseValueCount());
|
||||
|
||||
CommandLine::LooseValueIterator iter = cl.GetLooseValuesBegin();
|
||||
EXPECT_EQ(L"flim", *iter);
|
||||
++iter;
|
||||
EXPECT_EQ(L"flan", *iter);
|
||||
++iter;
|
||||
EXPECT_EQ(L"in the time of submarines...", *iter);
|
||||
++iter;
|
||||
EXPECT_TRUE(iter == cl.GetLooseValuesEnd());
|
||||
}
|
||||
|
||||
// These test the command line used to invoke the unit test.
|
||||
TEST(CommandLineTest, DefaultConstructor) {
|
||||
CommandLine cl;
|
||||
EXPECT_FALSE(cl.command_line_string().empty());
|
||||
EXPECT_FALSE(cl.program().empty());
|
||||
}
|
||||
|
||||
// Tests behavior with an empty input string.
|
||||
TEST(CommandLineTest, EmptyString) {
|
||||
CommandLine cl(L"");
|
||||
EXPECT_TRUE(cl.command_line_string().empty());
|
||||
EXPECT_TRUE(cl.program().empty());
|
||||
EXPECT_EQ(0, cl.GetLooseValueCount());
|
||||
}
|
||||
|
||||
// Test static functions for appending switches to a command line.
|
||||
TEST(CommandLineTest, AppendSwitches) {
|
||||
std::wstring cl_string = L"Program";
|
||||
std::wstring switch1 = L"switch1";
|
||||
std::wstring switch2 = L"switch2";
|
||||
std::wstring value = L"value";
|
||||
std::wstring switch3 = L"switch3";
|
||||
std::wstring value3 = L"a value with spaces";
|
||||
std::wstring switch4 = L"switch4";
|
||||
std::wstring value4 = L"\"a value with quotes\"";
|
||||
|
||||
CommandLine::AppendSwitch(&cl_string, switch1);
|
||||
CommandLine::AppendSwitchWithValue(&cl_string, switch2, value);
|
||||
CommandLine::AppendSwitchWithValue(&cl_string, switch3, value3);
|
||||
CommandLine::AppendSwitchWithValue(&cl_string, switch4, value4);
|
||||
CommandLine cl(cl_string);
|
||||
|
||||
EXPECT_TRUE(cl.HasSwitch(switch1));
|
||||
EXPECT_TRUE(cl.HasSwitch(switch2));
|
||||
EXPECT_EQ(value, cl.GetSwitchValue(switch2));
|
||||
EXPECT_TRUE(cl.HasSwitch(switch3));
|
||||
EXPECT_EQ(value3, cl.GetSwitchValue(switch3));
|
||||
EXPECT_TRUE(cl.HasSwitch(switch2));
|
||||
EXPECT_EQ(value4.substr(1, value4.length() - 2), cl.GetSwitchValue(switch4));
|
||||
}
|
464
base/condition_variable.cc
Normal file
@ -0,0 +1,464 @@
|
||||
// Copyright 2008, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include "base/condition_variable.h"
|
||||
|
||||
#include <stack>
|
||||
|
||||
#include "base/lock.h"
|
||||
#include "base/logging.h"
|
||||
|
||||
ConditionVariable::ConditionVariable(Lock* user_lock)
|
||||
: user_lock_(*user_lock),
|
||||
run_state_(RUNNING),
|
||||
allocation_counter_(0),
|
||||
recycling_list_size_(0) {
|
||||
DCHECK(user_lock);
|
||||
}
|
||||
|
||||
ConditionVariable::~ConditionVariable() {
|
||||
AutoLock auto_lock(internal_lock_);
|
||||
run_state_ = SHUTDOWN; // Prevent any more waiting.
|
||||
|
||||
DCHECK_EQ(recycling_list_size_, allocation_counter_);
|
||||
if (recycling_list_size_ != allocation_counter_) { // Rare shutdown problem.
|
||||
// There are threads of execution still in this->TimedWait() and yet the
|
||||
// caller has instigated the destruction of this instance :-/.
|
||||
// A common reason for such "overly hasty" destruction is that the caller
|
||||
// was not willing to wait for all the threads to terminate. Such hasty
|
||||
// actions are a violation of our usage contract, but we'll give the
|
||||
// waiting thread(s) one last chance to exit gracefully (prior to our
|
||||
// destruction).
|
||||
// Note: waiting_list_ *might* be empty, but recycling is still pending.
|
||||
AutoUnlock auto_unlock(internal_lock_);
|
||||
Broadcast(); // Make sure all waiting threads have been signaled.
|
||||
Sleep(10); // Give threads a chance to grab internal_lock_.
|
||||
// All contained threads should be blocked on user_lock_ by now :-).
|
||||
} // Reacquire internal_lock_.
|
||||
|
||||
DCHECK_EQ(recycling_list_size_, allocation_counter_);
|
||||
}
|
||||
|
||||
// Wait() atomically releases the caller's lock as it starts to Wait, and then
|
||||
// reacquires it when it is signaled.
|
||||
void ConditionVariable::TimedWait(const TimeDelta& max_time) {
|
||||
Event* waiting_event;
|
||||
HANDLE handle;
|
||||
{
|
||||
AutoLock auto_lock(internal_lock_);
|
||||
if (RUNNING != run_state_) return; // Destruction in progress.
|
||||
waiting_event = GetEventForWaiting();
|
||||
handle = waiting_event->handle();
|
||||
DCHECK(handle);
|
||||
} // Release internal_lock.
|
||||
|
||||
{
|
||||
AutoUnlock unlock(user_lock_); // Release caller's lock
|
||||
WaitForSingleObject(handle, static_cast<DWORD>(max_time.InMilliseconds()));
|
||||
// Minimize spurious signal creation window by recycling asap.
|
||||
AutoLock auto_lock(internal_lock_);
|
||||
RecycleEvent(waiting_event);
|
||||
// Release internal_lock_
|
||||
} // Reacquire callers lock to depth at entry.
|
||||
}
|
||||
|
||||
// Broadcast() is guaranteed to signal all threads that were waiting (i.e., had
|
||||
// a cv_event internally allocated for them) before Broadcast() was called.
|
||||
void ConditionVariable::Broadcast() {
|
||||
std::stack<HANDLE> handles; // See FAQ-question-10.
|
||||
{
|
||||
AutoLock auto_lock(internal_lock_);
|
||||
if (waiting_list_.IsEmpty())
|
||||
return;
|
||||
while (!waiting_list_.IsEmpty())
|
||||
// This is not a leak from waiting_list_. See FAQ-question 12.
|
||||
handles.push(waiting_list_.PopBack()->handle());
|
||||
} // Release internal_lock_.
|
||||
while (!handles.empty()) {
|
||||
SetEvent(handles.top());
|
||||
handles.pop();
|
||||
}
|
||||
}
|
||||
|
||||
// Signal() will select one of the waiting threads, and signal it (signal its
|
||||
// cv_event). For better performance we signal the thread that went to sleep
|
||||
// most recently (LIFO). If we want fairness, then we wake the thread that has
|
||||
// been sleeping the longest (FIFO).
|
||||
void ConditionVariable::Signal() {
|
||||
HANDLE handle;
|
||||
{
|
||||
AutoLock auto_lock(internal_lock_);
|
||||
if (waiting_list_.IsEmpty())
|
||||
return; // No one to signal.
|
||||
// Only performance option should be used.
|
||||
// This is not a leak from waiting_list. See FAQ-question 12.
|
||||
handle = waiting_list_.PopBack()->handle(); // LIFO.
|
||||
} // Release internal_lock_.
|
||||
SetEvent(handle);
|
||||
}
|
||||
|
||||
// GetEventForWaiting() provides a unique cv_event for any caller that needs to
|
||||
// wait. This means that (worst case) we may over time create as many cv_event
|
||||
// objects as there are threads simultaneously using this instance's Wait()
|
||||
// functionality.
|
||||
ConditionVariable::Event* ConditionVariable::GetEventForWaiting() {
|
||||
// We hold internal_lock, courtesy of Wait().
|
||||
Event* cv_event;
|
||||
if (0 == recycling_list_size_) {
|
||||
DCHECK(recycling_list_.IsEmpty());
|
||||
cv_event = new Event();
|
||||
cv_event->InitListElement();
|
||||
allocation_counter_++;
|
||||
// CHECK_NE is not defined in our codebase, so we have to use CHECK
|
||||
CHECK(cv_event->handle());
|
||||
} else {
|
||||
cv_event = recycling_list_.PopFront();
|
||||
recycling_list_size_--;
|
||||
}
|
||||
waiting_list_.PushBack(cv_event);
|
||||
return cv_event;
|
||||
}
|
||||
|
||||
// RecycleEvent() takes a cv_event that was previously used for Wait()ing, and
|
||||
// recycles it for use in future Wait() calls for this or other threads.
|
||||
// Note that there is a tiny chance that the cv_event is still signaled when we
|
||||
// obtain it, and that can cause spurious signals (if/when we re-use the
|
||||
// cv_event), but such is quite rare (see FAQ-question-5).
|
||||
void ConditionVariable::RecycleEvent(Event* used_event) {
|
||||
// We hold internal_lock, courtesy of Wait().
|
||||
// If the cv_event timed out, then it is necessary to remove it from
|
||||
// waiting_list_. If it was selected by Broadcast() or Signal(), then it is
|
||||
// already gone.
|
||||
used_event->Extract(); // Possibly redundant
|
||||
recycling_list_.PushBack(used_event);
|
||||
recycling_list_size_++;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
// The next section provides the implementation for the private Event class.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// Event provides a doubly-linked-list of events for use exclusively by the
|
||||
// ConditionVariable class.
|
||||
|
||||
// This custom container was crafted because no simple combination of STL
|
||||
// classes appeared to support the functionality required. The specific
|
||||
// unusual requirement for a linked-list-class is support for the Extract()
|
||||
// method, which can remove an element from a list, potentially for insertion
|
||||
// into a second list. Most critically, the Extract() method is idempotent,
|
||||
// turning the indicated element into an extracted singleton whether it was
|
||||
// contained in a list or not. This functionality allows one (or more) of
|
||||
// threads to do the extraction. The iterator that identifies this extractable
|
||||
// element (in this case, a pointer to the list element) can be used after
|
||||
// arbitrary manipulation of the (possibly) enclosing list container. In
|
||||
// general, STL containers do not provide iterators that can be used across
|
||||
// modifications (insertions/extractions) of the enclosing containers, and
|
||||
// certainly don't provide iterators that can be used if the identified
|
||||
// element is *deleted* (removed) from the container.
|
||||
|
||||
// It is possible to use multiple redundant containers, such as an STL list,
|
||||
// and an STL map, to achieve similar container semantics. This container has
|
||||
// only O(1) methods, while the corresponding (multiple) STL container approach
|
||||
// would have more complex O(log(N)) methods (yeah... N isn't that large).
|
||||
// Multiple containers also makes correctness more difficult to assert, as
|
||||
// data is redundantly stored and maintained, which is generally evil.
|
||||
|
||||
ConditionVariable::Event::Event() : handle_(0) {
|
||||
next_ = prev_ = this; // Self referencing circular.
|
||||
}
|
||||
|
||||
ConditionVariable::Event::~Event() {
|
||||
if (0 == handle_) {
|
||||
// This is the list holder
|
||||
while (!IsEmpty()) {
|
||||
Event* cv_event = PopFront();
|
||||
DCHECK(cv_event->ValidateAsItem());
|
||||
delete cv_event;
|
||||
}
|
||||
}
|
||||
DCHECK(IsSingleton());
|
||||
if (0 != handle_) {
|
||||
int ret_val = CloseHandle(handle_);
|
||||
DCHECK(ret_val);
|
||||
}
|
||||
}
|
||||
|
||||
// Change a container instance permanently into an element of a list.
|
||||
void ConditionVariable::Event::InitListElement() {
|
||||
DCHECK(!handle_);
|
||||
handle_ = CreateEvent(NULL, false, false, NULL);
|
||||
CHECK(handle_);
|
||||
}
|
||||
|
||||
// Methods for use on lists.
|
||||
bool ConditionVariable::Event::IsEmpty() const {
|
||||
DCHECK(ValidateAsList());
|
||||
return IsSingleton();
|
||||
}
|
||||
|
||||
void ConditionVariable::Event::PushBack(Event* other) {
|
||||
DCHECK(ValidateAsList());
|
||||
DCHECK(other->ValidateAsItem());
|
||||
DCHECK(other->IsSingleton());
|
||||
// Prepare other for insertion.
|
||||
other->prev_ = prev_;
|
||||
other->next_ = this;
|
||||
// Cut into list.
|
||||
prev_->next_ = other;
|
||||
prev_ = other;
|
||||
DCHECK(ValidateAsDistinct(other));
|
||||
}
|
||||
|
||||
ConditionVariable::Event* ConditionVariable::Event::PopFront() {
|
||||
DCHECK(ValidateAsList());
|
||||
DCHECK(!IsSingleton());
|
||||
return next_->Extract();
|
||||
}
|
||||
|
||||
ConditionVariable::Event* ConditionVariable::Event::PopBack() {
|
||||
DCHECK(ValidateAsList());
|
||||
DCHECK(!IsSingleton());
|
||||
return prev_->Extract();
|
||||
}
|
||||
|
||||
// Methods for use on list elements.
|
||||
// Accessor method.
|
||||
HANDLE ConditionVariable::Event::handle() const {
|
||||
DCHECK(ValidateAsItem());
|
||||
return handle_;
|
||||
}
|
||||
|
||||
// Pull an element from a list (if it's in one).
|
||||
ConditionVariable::Event* ConditionVariable::Event::Extract() {
|
||||
DCHECK(ValidateAsItem());
|
||||
if (!IsSingleton()) {
|
||||
// Stitch neighbors together.
|
||||
next_->prev_ = prev_;
|
||||
prev_->next_ = next_;
|
||||
// Make extractee into a singleton.
|
||||
prev_ = next_ = this;
|
||||
}
|
||||
DCHECK(IsSingleton());
|
||||
return this;
|
||||
}
|
||||
|
||||
// Method for use on a list element or on a list.
|
||||
bool ConditionVariable::Event::IsSingleton() const {
|
||||
DCHECK(ValidateLinks());
|
||||
return next_ == this;
|
||||
}
|
||||
|
||||
// Provide pre/post conditions to validate correct manipulations.
|
||||
bool ConditionVariable::Event::ValidateAsDistinct(Event* other) const {
|
||||
return ValidateLinks() && other->ValidateLinks() && (this != other);
|
||||
}
|
||||
|
||||
bool ConditionVariable::Event::ValidateAsItem() const {
|
||||
return (0 != handle_) && ValidateLinks();
|
||||
}
|
||||
|
||||
bool ConditionVariable::Event::ValidateAsList() const {
|
||||
return (0 == handle_) && ValidateLinks();
|
||||
}
|
||||
|
||||
bool ConditionVariable::Event::ValidateLinks() const {
|
||||
// Make sure both of our neighbors have links that point back to us.
|
||||
// We don't do the O(n) check and traverse the whole loop, and instead only
|
||||
// do a local check to (and returning from) our immediate neighbors.
|
||||
return (next_->prev_ == this) && (prev_->next_ == this);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
FAQ On subtle implementation details:
|
||||
|
||||
1) What makes this problem subtle? Please take a look at "Strategies
|
||||
for Implementing POSIX Condition Variables on Win32" by Douglas
|
||||
C. Schmidt and Irfan Pyarali.
|
||||
http://www.cs.wustl.edu/~schmidt/win32-cv-1.html It includes
|
||||
discussions of numerous flawed strategies for implementing this
|
||||
functionality. I'm not convinced that even the final proposed
|
||||
implementation has semantics that are as nice as this implementation
|
||||
(especially with regard to Broadcast() and the impact on threads that
|
||||
try to Wait() after a Broadcast() has been called, but before all the
|
||||
original waiting threads have been signaled).
|
||||
|
||||
2) Why can't you use a single wait_event for all threads that call
|
||||
Wait()? See FAQ-question-1, or consider the following: If a single
|
||||
event were used, then numerous threads calling Wait() could release
|
||||
their cs locks, and be preempted just before calling
|
||||
WaitForSingleObject(). If a call to Broadcast() was then presented on
|
||||
a second thread, it would be impossible to actually signal all
|
||||
waiting(?) threads. Some number of SetEvent() calls *could* be made,
|
||||
but there could be no guarantee that those led to to more than one
|
||||
signaled thread (SetEvent()'s may be discarded after the first!), and
|
||||
there could be no guarantee that the SetEvent() calls didn't just
|
||||
awaken "other" threads that hadn't even started waiting yet (oops).
|
||||
Without any limit on the number of requisite SetEvent() calls, the
|
||||
system would be forced to do many such calls, allowing many new waits
|
||||
to receive spurious signals.
|
||||
|
||||
3) How does this implementation cause spurious signal events? The
|
||||
cause in this implementation involves a race between a signal via
|
||||
time-out and a signal via Signal() or Broadcast(). The series of
|
||||
actions leading to this are:
|
||||
|
||||
a) Timer fires, and a waiting thread exits the line of code:
|
||||
|
||||
WaitForSingleObject(waiting_event, max_time.InMilliseconds());
|
||||
|
||||
b) That thread (in (a)) is randomly pre-empted after the above line,
|
||||
leaving the waiting_event reset (unsignaled) and still in the
|
||||
waiting_list_.
|
||||
|
||||
c) A call to Signal() (or Broadcast()) on a second thread proceeds, and
|
||||
selects the waiting cv_event (identified in step (b)) as the event to revive
|
||||
via a call to SetEvent().
|
||||
|
||||
d) The Signal() method (step c) calls SetEvent() on waiting_event (step b).
|
||||
|
||||
e) The waiting cv_event (step b) is now signaled, but no thread is
|
||||
waiting on it.
|
||||
|
||||
f) When that waiting_event (step b) is reused, it will immediately
|
||||
be signaled (spuriously).
|
||||
|
||||
|
||||
4) Why do you recycle events, and cause spurious signals? First off,
|
||||
the spurious events are very rare. They can only (I think) appear
|
||||
when the race described in FAQ-question-3 takes place. This should be
|
||||
very rare. Most(?) uses will involve only timer expiration, or only
|
||||
Signal/Broadcast() actions. When both are used, it will be rare that
|
||||
the race will appear, and it would require MANY Wait() and signaling
|
||||
activities. If this implementation did not recycle events, then it
|
||||
would have to create and destroy events for every call to Wait().
|
||||
That allocation/deallocation and associated construction/destruction
|
||||
would be costly (per wait), and would only be a rare benefit (when the
|
||||
race was "lost" and a spurious signal took place). That would be bad
|
||||
(IMO) optimization trade-off. Finally, such spurious events are
|
||||
allowed by the specification of condition variables (such as
|
||||
implemented in Vista), and hence it is better if any user accommodates
|
||||
such spurious events (see usage note in condition_variable.h).
|
||||
|
||||
5) Why don't you reset events when you are about to recycle them, or
|
||||
about to reuse them, so that the spurious signals don't take place?
|
||||
The thread described in FAQ-question-3 step c may be pre-empted for an
|
||||
arbitrary length of time before proceeding to step d. As a result,
|
||||
the wait_event may actually be re-used *before* step (e) is reached.
|
||||
As a result, calling reset would not help significantly.
|
||||
|
||||
6) How is it that the callers lock is released atomically with the
|
||||
entry into a wait state? We commit to the wait activity when we
|
||||
allocate the wait_event for use in a given call to Wait(). This
|
||||
allocation takes place before the caller's lock is released (and
|
||||
actually before our internal_lock_ is released). That allocation is
|
||||
the defining moment when "the wait state has been entered," as that
|
||||
thread *can* now be signaled by a call to Broadcast() or Signal().
|
||||
Hence we actually "commit to wait" before releasing the lock, making
|
||||
the pair effectively atomic.
|
||||
|
||||
8) Why do you need to lock your data structures during waiting, as the
|
||||
caller is already in possession of a lock? We need to Acquire() and
|
||||
Release() our internal lock during Signal() and Broadcast(). If we tried
|
||||
to use a callers lock for this purpose, we might conflict with their
|
||||
external use of the lock. For example, the caller may use to consistently
|
||||
hold a lock on one thread while calling Signal() on another, and that would
|
||||
block Signal().
|
||||
|
||||
9) Couldn't a more efficient implementation be provided if you
|
||||
preclude using more than one external lock in conjunction with a
|
||||
single ConditionVariable instance? Yes, at least it could be viewed
|
||||
as a simpler API (since you don't have to reiterate the lock argument
|
||||
in each Wait() call). One of the constructors now takes a specific
|
||||
lock as an argument, and a there are corresponding Wait() calls that
|
||||
don't specify a lock now. It turns that the resulting implmentation
|
||||
can't be made more efficient, as the internal lock needs to be used by
|
||||
Signal() and Broadcast(), to access internal data structures. As a
|
||||
result, I was not able to utilize the user supplied lock (which is
|
||||
being used by the user elsewhere presumably) to protect the private
|
||||
member access.
|
||||
|
||||
9) Since you have a second lock, how can be be sure that there is no
|
||||
possible deadlock scenario? Our internal_lock_ is always the last
|
||||
lock acquired, and the first one released, and hence a deadlock (due
|
||||
to critical section problems) is impossible as a consequence of our
|
||||
lock.
|
||||
|
||||
10) When doing a Broadcast(), why did you copy all the events into
|
||||
an STL queue, rather than making a linked-loop, and iterating over it?
|
||||
The iterating during Broadcast() is done so outside the protection
|
||||
of the internal lock. As a result, other threads, such as the thread
|
||||
wherein a related event is waiting, could asynchronously manipulate
|
||||
the links around a cv_event. As a result, the link structure cannot
|
||||
be used outside a lock. Broadcast() could iterate over waiting
|
||||
events by cycling in-and-out of the protection of the internal_lock,
|
||||
but that appears more expensive than copying the list into an STL
|
||||
stack.
|
||||
|
||||
11) Why did the lock.h file need to be modified so much for this
|
||||
change? Central to a Condition Variable is the atomic release of a
|
||||
lock during a Wait(). This places Wait() functionality exactly
|
||||
mid-way between the two classes, Lock and Condition Variable. Given
|
||||
that there can be nested Acquire()'s of locks, and Wait() had to
|
||||
Release() completely a held lock, it was necessary to augment the Lock
|
||||
class with a recursion counter. Even more subtle is the fact that the
|
||||
recursion counter (in a Lock) must be protected, as many threads can
|
||||
access it asynchronously. As a positive fallout of this, there are
|
||||
now some DCHECKS to be sure no one Release()s a Lock more than they
|
||||
Acquire()ed it, and there is ifdef'ed functionality that can detect
|
||||
nested locks (legal under windows, but not under Posix).
|
||||
|
||||
12) Why is it that the cv_events removed from list in Broadcast() and Signal()
|
||||
are not leaked? How are they recovered?? The cv_events that appear to leak are
|
||||
taken from the waiting_list_. For each element in that list, there is currently
|
||||
a thread in or around the WaitForSingleObject() call of Wait(), and those
|
||||
threads have references to these otherwise leaked events. They are passed as
|
||||
arguments to be recycled just aftre returning from WaitForSingleObject().
|
||||
|
||||
13) Why did you use a custom container class (the linked list), when STL has
|
||||
perfectly good containers, such as an STL list? The STL list, as with any
|
||||
container, does not guarantee the utility of an iterator across manipulation
|
||||
(such as insertions and deletions) of the underlying container. The custom
|
||||
double-linked-list container provided that assurance. I don't believe any
|
||||
combination of STL containers provided the services that were needed at the same
|
||||
O(1) efficiency as the custom linked list. The unusual requirement
|
||||
for the container class is that a reference to an item within a container (an
|
||||
iterator) needed to be maintained across an arbitrary manipulation of the
|
||||
container. This requirement exposes itself in the Wait() method, where a
|
||||
waiting_event must be selected prior to the WaitForSingleObject(), and then it
|
||||
must be used as part of recycling to remove the related instance from the
|
||||
waiting_list. A hash table (STL map) could be used, but I was embarrased to
|
||||
use a complex and relatively low efficiency container when a doubly linked list
|
||||
provided O(1) performance in all required operations. Since other operations
|
||||
to provide performance-and/or-fairness required queue (FIFO) and list (LIFO)
|
||||
containers, I would also have needed to use an STL list/queue as well as an STL
|
||||
map. In the end I decided it would be "fun" to just do it right, and I
|
||||
put so many assertions (DCHECKs) into the container class that it is trivial to
|
||||
code review and validate its correctness.
|
||||
|
||||
*/
|
195
base/condition_variable.h
Normal file
@ -0,0 +1,195 @@
|
||||
// Copyright 2008, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// ConditionVariable is a reasonable attempt at simulating
|
||||
// the newer Posix and Vista-only construct for condition variable
|
||||
// synchronization. This functionality is very helpful for having several
|
||||
// threads wait for an event, as is common with a thread pool
|
||||
// managed by a master. The meaning of such an event in the
|
||||
// (worker) thread pool scenario is that additional tasks are
|
||||
// now available for processing. It is used in Chrome in the
|
||||
// DNS prefetching system to notify worker threads that a queue
|
||||
// now has items (tasks) which need to be tended to.
|
||||
// A related use would have a pool manager waiting on a
|
||||
// ConditionVariable, waiting for a thread in the pool to announce
|
||||
// (signal) that there is now more room in a (bounded size) communications
|
||||
// queue for the manager to deposit tasks, or, as a second example, that
|
||||
// the queue of tasks is completely empty and all workers are waiting.
|
||||
|
||||
// USAGE NOTE 1: spurious signal events are possible with this and
|
||||
// most implementations of condition variables. As a result, be
|
||||
// *sure* to retest your condition before proceeding. The following
|
||||
// is a good example of doing this correctly:
|
||||
|
||||
// while (!work_to_be_done()) Wait(...);
|
||||
|
||||
// In contrast do NOT do the following:
|
||||
|
||||
// if (!work_to_be_done()) Wait(...); // Don't do this.
|
||||
|
||||
// Especially avoid the above if you are relying on some other thread only
|
||||
// issuing a signal up *if* there is work-to-do. There can/will
|
||||
// be spurious signals. Recheck state on waiting thread before
|
||||
// assuming the signal was intentional. Caveat caller ;-).
|
||||
|
||||
// USAGE NOTE 2: Broadcast() frees up all waiting threads at once,
|
||||
// which leads to contention for the locks they all held when they
|
||||
// called Wait(). This results in POOR performance. A much better
|
||||
// approach to getting a lot of threads out of Wait() is to have each
|
||||
// thread (upon exiting Wait()) call Signal() to free up another
|
||||
// Wait'ing thread. Look at condition_variable_unittest.cc for
|
||||
// both examples.
|
||||
|
||||
// Broadcast() can be used nicely during teardown, as it gets the job
|
||||
// done, and leaves no sleeping threads... and performance is less
|
||||
// critical at that point.
|
||||
|
||||
// The semantics of Broadcast() are carefully crafted so that *all*
|
||||
// threads that were waiting when the request was made will indeed
|
||||
// get signaled. Some implementations mess up, and don't signal them
|
||||
// all, while others allow the wait to be effectively turned off (for
|
||||
// for a while while waiting threads come around). This implementation
|
||||
// appears correct, as it will not "lose" any signals, and will guarantee
|
||||
// that all threads get signaled by Broadcast().
|
||||
|
||||
// This implementation offers support for "performance" in its selection of
|
||||
// which thread to revive. Performance, in direct contrast with "fairness,"
|
||||
// assures that the thread that most recently began to Wait() is selected by
|
||||
// Signal to revive. Fairness would (if publicly supported) assure that the
|
||||
// thread that has Wait()ed the longest is selected. The default policy
|
||||
// may improve performance, as the selected thread may have a greater chance of
|
||||
// having some of its stack data in various CPU caches.
|
||||
|
||||
// For a discussion of the many very subtle implementation details, see the FAQ
|
||||
// at the end of condition_variable.cc.
|
||||
|
||||
#ifndef BASE_CONDITION_VARIABLE_H__
|
||||
#define BASE_CONDITION_VARIABLE_H__
|
||||
|
||||
#include "base/lock.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/scoped_ptr.h"
|
||||
#include "base/time.h"
|
||||
|
||||
class Lock;
|
||||
|
||||
class ConditionVariable {
|
||||
public:
|
||||
// Construct a cv for use with ONLY one user lock.
|
||||
explicit ConditionVariable(Lock* user_lock);
|
||||
|
||||
~ConditionVariable();
|
||||
|
||||
// Wait() releases the caller's critical section atomically as it starts to
|
||||
// sleep, and the reacquires it when it is signaled.
|
||||
void TimedWait(const TimeDelta& max_time);
|
||||
void Wait() {
|
||||
// Default to "wait forever" timing, which means have to get a Signal()
|
||||
// or Broadcast() to come out of this wait state.
|
||||
TimedWait(TimeDelta::FromMilliseconds(INFINITE));
|
||||
}
|
||||
|
||||
// Broadcast() revives all waiting threads.
|
||||
void Broadcast();
|
||||
// Signal() revives one waiting thread.
|
||||
void Signal();
|
||||
|
||||
private:
|
||||
// Define Event class that is used to form circularly linked lists.
|
||||
// The list container is an element with NULL as its handle_ value.
|
||||
// The actual list elements have a non-zero handle_ value.
|
||||
// All calls to methods MUST be done under protection of a lock so that links
|
||||
// can be validated. Without the lock, some links might asynchronously
|
||||
// change, and the assertions would fail (as would list change operations).
|
||||
class Event {
|
||||
public:
|
||||
// Default constructor with no arguments creates a list container.
|
||||
Event();
|
||||
~Event();
|
||||
|
||||
// InitListElement transitions an instance from a container, to an element.
|
||||
void InitListElement();
|
||||
|
||||
// Methods for use on lists.
|
||||
bool IsEmpty() const;
|
||||
void PushBack(Event* other);
|
||||
Event* PopFront();
|
||||
Event* PopBack();
|
||||
|
||||
// Methods for use on list elements.
|
||||
// Accessor method.
|
||||
HANDLE handle() const;
|
||||
// Pull an element from a list (if it's in one).
|
||||
Event* Extract();
|
||||
|
||||
// Method for use on a list element or on a list.
|
||||
bool IsSingleton() const;
|
||||
|
||||
private:
|
||||
// Provide pre/post conditions to validate correct manipulations.
|
||||
bool ValidateAsDistinct(Event* other) const;
|
||||
bool ValidateAsItem() const;
|
||||
bool ValidateAsList() const;
|
||||
bool ValidateLinks() const;
|
||||
|
||||
HANDLE handle_;
|
||||
Event* next_;
|
||||
Event* prev_;
|
||||
DISALLOW_EVIL_CONSTRUCTORS(Event);
|
||||
};
|
||||
|
||||
// Note that RUNNING is an unlikely number to have in RAM by accident.
|
||||
// This helps with defensive destructor coding in the face of user error.
|
||||
enum RunState { SHUTDOWN = 0, RUNNING = 64213 };
|
||||
|
||||
// Internal implementation methods supporting Wait().
|
||||
Event* GetEventForWaiting();
|
||||
void RecycleEvent(Event* used_event);
|
||||
|
||||
RunState run_state_;
|
||||
|
||||
// Private critical section for access to member data.
|
||||
Lock internal_lock_;
|
||||
// Lock that is acquired before calling Wait().
|
||||
Lock& user_lock_;
|
||||
|
||||
// Events that threads are blocked on.
|
||||
Event waiting_list_;
|
||||
|
||||
// Free list for old events.
|
||||
Event recycling_list_;
|
||||
int recycling_list_size_;
|
||||
|
||||
// The number of allocated, but not yet deleted events.
|
||||
int allocation_counter_;
|
||||
|
||||
DISALLOW_EVIL_CONSTRUCTORS(ConditionVariable);
|
||||
};
|
||||
|
||||
#endif // BASE_CONDITION_VARIABLE_H__
|
707
base/condition_variable_test.cc
Normal file
@ -0,0 +1,707 @@
|
||||
// Copyright 2008, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Multi-threaded tests of ConditionVariable class.
|
||||
|
||||
#include <time.h>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
#include "base/check_handler.h"
|
||||
#include "base/condition_variable.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/scoped_ptr.h"
|
||||
#include "base/spin_wait.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
|
||||
namespace {
|
||||
//------------------------------------------------------------------------------
|
||||
// Define our test class, with several common variables.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
class ConditionVariableTest : public testing::Test {
|
||||
public:
|
||||
const TimeDelta kZeroMs;
|
||||
const TimeDelta kTenMs;
|
||||
const TimeDelta kThirtyMs;
|
||||
const TimeDelta kFortyFiveMs;
|
||||
const TimeDelta kSixtyMs;
|
||||
const TimeDelta kOneHundredMs;
|
||||
|
||||
explicit ConditionVariableTest()
|
||||
: kZeroMs(TimeDelta::FromMilliseconds(0)),
|
||||
kTenMs(TimeDelta::FromMilliseconds(10)),
|
||||
kThirtyMs(TimeDelta::FromMilliseconds(30)),
|
||||
kFortyFiveMs(TimeDelta::FromMilliseconds(45)),
|
||||
kSixtyMs(TimeDelta::FromMilliseconds(60)),
|
||||
kOneHundredMs(TimeDelta::FromMilliseconds(100)) {
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Define a class that will control activities an several multi-threaded tests.
|
||||
// The general structure of multi-threaded tests is that a test case will
|
||||
// construct an instance of a WorkQueue. The WorkQueue will spin up some
|
||||
// threads and control them thoughout their lifetime, as well as maintaining
|
||||
// a central respository of the work thread's activity. Finally, the WorkQueue
|
||||
// will command the the worker threads to terminate. At that point, the test
|
||||
// cases will validate that the WorkQueue has records showing that the desired
|
||||
// activities were performed.
|
||||
//------------------------------------------------------------------------------
|
||||
// Forward declare the WorkerProcess task
|
||||
static DWORD WINAPI WorkerProcess(void* p);
|
||||
|
||||
// Callers are responsible for synchronizing access to the following class.
|
||||
// The WorkQueue::lock_, as accessed via WorkQueue::lock(), should be used for
|
||||
// all synchronized access.
|
||||
class WorkQueue {
|
||||
public:
|
||||
explicit WorkQueue(int thread_count);
|
||||
~WorkQueue();
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Worker threads only call the following methods.
|
||||
// They should use the lock to get exclusive access.
|
||||
int GetThreadId(); // Get an ID assigned to a thread..
|
||||
bool EveryIdWasAllocated() const; // Indicates that all IDs were handed out.
|
||||
TimeDelta GetAnAssignment(int thread_id); // Get a work task duration.
|
||||
void WorkIsCompleted(int thread_id);
|
||||
|
||||
int task_count() const;
|
||||
bool allow_help_requests() const; // Workers can signal more workers.
|
||||
bool shutdown() const; // Check if shutdown has been requested.
|
||||
int shutdown_task_count() const;
|
||||
|
||||
void thread_shutting_down();
|
||||
Lock* lock();
|
||||
|
||||
ConditionVariable* work_is_available();
|
||||
ConditionVariable* all_threads_have_ids();
|
||||
ConditionVariable* no_more_tasks();
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// The rest of the methods are for use by the controlling master thread (the
|
||||
// test case code).
|
||||
void ResetHistory();
|
||||
int GetMinCompletionsByWorkerThread() const;
|
||||
int GetMaxCompletionsByWorkerThread() const;
|
||||
int GetNumThreadsTakingAssignments() const;
|
||||
int GetNumThreadsCompletingTasks() const;
|
||||
int GetNumberOfCompletedTasks() const;
|
||||
|
||||
void SetWorkTime(TimeDelta delay);
|
||||
void SetTaskCount(int count);
|
||||
void SetAllowHelp(bool allow);
|
||||
|
||||
void SetShutdown();
|
||||
|
||||
private:
|
||||
// Both worker threads and controller use the following to synchronize.
|
||||
Lock lock_;
|
||||
ConditionVariable work_is_available_; // To tell threads there is work.
|
||||
|
||||
// Conditions to notify the controlling process (if it is interested).
|
||||
ConditionVariable all_threads_have_ids_; // All threads are running.
|
||||
ConditionVariable no_more_tasks_; // Task count is zero.
|
||||
|
||||
const int thread_count_;
|
||||
scoped_array<HANDLE> handles_;
|
||||
std::vector<int> assignment_history_; // Number of assignment per worker.
|
||||
std::vector<int> completion_history_; // Number of completions per worker.
|
||||
int thread_started_counter_; // Used to issue unique id to workers.
|
||||
int shutdown_task_count_; // Number of tasks told to shutdown
|
||||
int task_count_; // Number of assignment tasks waiting to be processed.
|
||||
TimeDelta worker_delay_; // Time each task takes to complete.
|
||||
bool allow_help_requests_; // Workers can signal more workers.
|
||||
bool shutdown_; // Set when threads need to terminate.
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Define the standard worker task. Several tests will spin out many of these
|
||||
// threads.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// The multithread tests involve several threads with a task to perform as
|
||||
// directed by an instance of the class WorkQueue.
|
||||
// The task is to:
|
||||
// a) Check to see if there are more tasks (there is a task counter).
|
||||
// a1) Wait on condition variable if there are no tasks currently.
|
||||
// b) Call a function to see what should be done.
|
||||
// c) Do some computation based on the number of milliseconds returned in (b).
|
||||
// d) go back to (a).
|
||||
|
||||
// WorkerProcess() implements the above task for all threads.
|
||||
// It calls the controlling object to tell the creator about progress, and to
|
||||
// ask about tasks.
|
||||
static DWORD WINAPI WorkerProcess(void* p) {
|
||||
int thread_id;
|
||||
class WorkQueue* queue = reinterpret_cast<WorkQueue*>(p);
|
||||
{
|
||||
AutoLock auto_lock(*queue->lock());
|
||||
thread_id = queue->GetThreadId();
|
||||
if (queue->EveryIdWasAllocated())
|
||||
queue->all_threads_have_ids()->Signal(); // Tell creator we're ready.
|
||||
}
|
||||
|
||||
Lock private_lock; // Used to waste time on "our work".
|
||||
while (1) { // This is the main consumer loop.
|
||||
TimeDelta work_time;
|
||||
bool could_use_help;
|
||||
{
|
||||
AutoLock auto_lock(*queue->lock());
|
||||
while (0 == queue->task_count() && !queue->shutdown()) {
|
||||
queue->work_is_available()->Wait();
|
||||
}
|
||||
if (queue->shutdown()) {
|
||||
// Ack the notification of a shutdown message back to the controller.
|
||||
queue->thread_shutting_down();
|
||||
return 0; // Terminate.
|
||||
}
|
||||
// Get our task duration from the queue.
|
||||
work_time = queue->GetAnAssignment(thread_id);
|
||||
could_use_help = (queue->task_count() > 0) &&
|
||||
queue->allow_help_requests();
|
||||
} // Release lock
|
||||
|
||||
// Do work (outside of locked region.
|
||||
if (could_use_help)
|
||||
queue->work_is_available()->Signal(); // Get help from other threads.
|
||||
|
||||
if (work_time > TimeDelta::FromMilliseconds(0)) {
|
||||
// We could just sleep(), but we'll instead further exercise the
|
||||
// condition variable class, and do a timed wait.
|
||||
AutoLock auto_lock(private_lock);
|
||||
ConditionVariable private_cv(&private_lock);
|
||||
private_cv.TimedWait(work_time); // Unsynchronized waiting.
|
||||
}
|
||||
|
||||
{
|
||||
AutoLock auto_lock(*queue->lock());
|
||||
// Send notification that we completed our "work."
|
||||
queue->WorkIsCompleted(thread_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
// The next section contains the actual tests.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
TEST_F(ConditionVariableTest, StartupShutdownTest) {
|
||||
Lock lock;
|
||||
|
||||
// First try trivial startup/shutdown.
|
||||
{
|
||||
ConditionVariable cv1(&lock);
|
||||
} // Call for cv1 destruction.
|
||||
|
||||
// Exercise with at least a few waits.
|
||||
ConditionVariable cv(&lock);
|
||||
|
||||
lock.Acquire();
|
||||
cv.TimedWait(kTenMs); // Wait for 10 ms.
|
||||
cv.TimedWait(kTenMs); // Wait for 10 ms.
|
||||
lock.Release();
|
||||
|
||||
lock.Acquire();
|
||||
cv.TimedWait(kTenMs); // Wait for 10 ms.
|
||||
cv.TimedWait(kTenMs); // Wait for 10 ms.
|
||||
cv.TimedWait(kTenMs); // Wait for 10 ms.
|
||||
lock.Release();
|
||||
} // Call for cv destruction.
|
||||
|
||||
TEST_F(ConditionVariableTest, LockedExpressionTest) {
|
||||
int i = 0;
|
||||
Lock lock;
|
||||
|
||||
// Old LOCKED_EXPRESSION macro caused syntax errors here.
|
||||
// ... yes... compiler will optimize this example.
|
||||
// Syntax error is what I'm after precluding.
|
||||
if (0)
|
||||
LOCKED_EXPRESSION(lock, i = 1);
|
||||
else
|
||||
LOCKED_EXPRESSION(lock, i = 2);
|
||||
|
||||
EXPECT_EQ(2, i);
|
||||
}
|
||||
|
||||
TEST_F(ConditionVariableTest, TimeoutTest) {
|
||||
Lock lock;
|
||||
ConditionVariable cv(&lock);
|
||||
lock.Acquire();
|
||||
|
||||
TimeTicks start = TimeTicks::Now();
|
||||
const TimeDelta WAIT_TIME = TimeDelta::FromMilliseconds(300);
|
||||
// Allow for clocking rate granularity.
|
||||
const TimeDelta FUDGE_TIME = TimeDelta::FromMilliseconds(50);
|
||||
|
||||
cv.TimedWait(WAIT_TIME + FUDGE_TIME);
|
||||
TimeDelta duration = TimeTicks::Now() - start;
|
||||
// We can't use EXPECT_GE here as the TimeDelta class does not support the
|
||||
// required stream conversion.
|
||||
EXPECT_TRUE(duration >= WAIT_TIME);
|
||||
|
||||
lock.Release();
|
||||
}
|
||||
|
||||
TEST_F(ConditionVariableTest, MultiThreadConsumerTest) {
|
||||
const int kThreadCount = 10;
|
||||
WorkQueue queue(kThreadCount); // Start the threads.
|
||||
|
||||
Lock private_lock; // Used locally for master to wait.
|
||||
AutoLock private_held_lock(private_lock);
|
||||
ConditionVariable private_cv(&private_lock);
|
||||
|
||||
{
|
||||
AutoLock auto_lock(*queue.lock());
|
||||
while (!queue.EveryIdWasAllocated())
|
||||
queue.all_threads_have_ids()->Wait();
|
||||
}
|
||||
|
||||
// Wait a bit more to allow threads to reach their wait state.
|
||||
private_cv.TimedWait(kTenMs);
|
||||
|
||||
{
|
||||
// Since we have no tasks, all threads should be waiting by now.
|
||||
AutoLock auto_lock(*queue.lock());
|
||||
EXPECT_EQ(0, queue.GetNumThreadsTakingAssignments());
|
||||
EXPECT_EQ(0, queue.GetNumThreadsCompletingTasks());
|
||||
EXPECT_EQ(0, queue.task_count());
|
||||
EXPECT_EQ(0, queue.GetMaxCompletionsByWorkerThread());
|
||||
EXPECT_EQ(0, queue.GetMinCompletionsByWorkerThread());
|
||||
EXPECT_EQ(0, queue.GetNumberOfCompletedTasks());
|
||||
|
||||
// Set up to make one worker do 3 30ms tasks.
|
||||
queue.ResetHistory();
|
||||
queue.SetTaskCount(3);
|
||||
queue.SetWorkTime(kThirtyMs);
|
||||
queue.SetAllowHelp(false);
|
||||
}
|
||||
queue.work_is_available()->Signal(); // Start up one thread.
|
||||
// Wait to allow solo worker insufficient time to get done.
|
||||
private_cv.TimedWait(kFortyFiveMs); // Should take about 90 ms.
|
||||
|
||||
{
|
||||
// Check that all work HASN'T completed yet.
|
||||
AutoLock auto_lock(*queue.lock());
|
||||
EXPECT_EQ(1, queue.GetNumThreadsTakingAssignments());
|
||||
EXPECT_EQ(1, queue.GetNumThreadsCompletingTasks());
|
||||
EXPECT_GT(2, queue.task_count()); // 2 should have started.
|
||||
EXPECT_GT(3, queue.GetMaxCompletionsByWorkerThread());
|
||||
EXPECT_EQ(0, queue.GetMinCompletionsByWorkerThread());
|
||||
EXPECT_EQ(1, queue.GetNumberOfCompletedTasks());
|
||||
}
|
||||
// Wait to allow solo workers to get done.
|
||||
private_cv.TimedWait(kSixtyMs); // Should take about 45ms more.
|
||||
|
||||
{
|
||||
// Check that all work was done by one thread id.
|
||||
AutoLock auto_lock(*queue.lock());
|
||||
EXPECT_EQ(1, queue.GetNumThreadsTakingAssignments());
|
||||
EXPECT_EQ(1, queue.GetNumThreadsCompletingTasks());
|
||||
EXPECT_EQ(0, queue.task_count());
|
||||
EXPECT_EQ(3, queue.GetMaxCompletionsByWorkerThread());
|
||||
EXPECT_EQ(0, queue.GetMinCompletionsByWorkerThread());
|
||||
EXPECT_EQ(3, queue.GetNumberOfCompletedTasks());
|
||||
|
||||
// Set up to make each task include getting help from another worker.
|
||||
queue.ResetHistory();
|
||||
queue.SetTaskCount(3);
|
||||
queue.SetWorkTime(kThirtyMs);
|
||||
queue.SetAllowHelp(true);
|
||||
}
|
||||
queue.work_is_available()->Signal(); // But each worker can signal another.
|
||||
// Wait to allow the 3 workers to get done.
|
||||
private_cv.TimedWait(kFortyFiveMs); // Should take about 30 ms.
|
||||
|
||||
{
|
||||
AutoLock auto_lock(*queue.lock());
|
||||
EXPECT_EQ(3, queue.GetNumThreadsTakingAssignments());
|
||||
EXPECT_EQ(3, queue.GetNumThreadsCompletingTasks());
|
||||
EXPECT_EQ(0, queue.task_count());
|
||||
EXPECT_EQ(1, queue.GetMaxCompletionsByWorkerThread());
|
||||
EXPECT_EQ(0, queue.GetMinCompletionsByWorkerThread());
|
||||
EXPECT_EQ(3, queue.GetNumberOfCompletedTasks());
|
||||
|
||||
// Try to ask all workers to help, and only a few will do the work.
|
||||
queue.ResetHistory();
|
||||
queue.SetTaskCount(3);
|
||||
queue.SetWorkTime(kThirtyMs);
|
||||
queue.SetAllowHelp(false);
|
||||
}
|
||||
queue.work_is_available()->Broadcast(); // Make them all try.
|
||||
// Wait to allow the 3 workers to get done.
|
||||
private_cv.TimedWait(kFortyFiveMs);
|
||||
|
||||
{
|
||||
AutoLock auto_lock(*queue.lock());
|
||||
EXPECT_EQ(3, queue.GetNumThreadsTakingAssignments());
|
||||
EXPECT_EQ(3, queue.GetNumThreadsCompletingTasks());
|
||||
EXPECT_EQ(0, queue.task_count());
|
||||
EXPECT_EQ(1, queue.GetMaxCompletionsByWorkerThread());
|
||||
EXPECT_EQ(0, queue.GetMinCompletionsByWorkerThread());
|
||||
EXPECT_EQ(3, queue.GetNumberOfCompletedTasks());
|
||||
|
||||
// Set up to make each task get help from another worker.
|
||||
queue.ResetHistory();
|
||||
queue.SetTaskCount(3);
|
||||
queue.SetWorkTime(kThirtyMs);
|
||||
queue.SetAllowHelp(true); // Allow (unnecessary) help requests.
|
||||
}
|
||||
queue.work_is_available()->Broadcast(); // We already signal all threads.
|
||||
// Wait to allow the 3 workers to get done.
|
||||
private_cv.TimedWait(kOneHundredMs);
|
||||
|
||||
{
|
||||
AutoLock auto_lock(*queue.lock());
|
||||
EXPECT_EQ(3, queue.GetNumThreadsTakingAssignments());
|
||||
EXPECT_EQ(3, queue.GetNumThreadsCompletingTasks());
|
||||
EXPECT_EQ(0, queue.task_count());
|
||||
EXPECT_EQ(1, queue.GetMaxCompletionsByWorkerThread());
|
||||
EXPECT_EQ(0, queue.GetMinCompletionsByWorkerThread());
|
||||
EXPECT_EQ(3, queue.GetNumberOfCompletedTasks());
|
||||
|
||||
// Set up to make each task get help from another worker.
|
||||
queue.ResetHistory();
|
||||
queue.SetTaskCount(20);
|
||||
queue.SetWorkTime(kThirtyMs);
|
||||
queue.SetAllowHelp(true);
|
||||
}
|
||||
queue.work_is_available()->Signal(); // But each worker can signal another.
|
||||
// Wait to allow the 10 workers to get done.
|
||||
private_cv.TimedWait(kOneHundredMs); // Should take about 60 ms.
|
||||
|
||||
{
|
||||
AutoLock auto_lock(*queue.lock());
|
||||
EXPECT_EQ(10, queue.GetNumThreadsTakingAssignments());
|
||||
EXPECT_EQ(10, queue.GetNumThreadsCompletingTasks());
|
||||
EXPECT_EQ(0, queue.task_count());
|
||||
EXPECT_EQ(2, queue.GetMaxCompletionsByWorkerThread());
|
||||
EXPECT_EQ(2, queue.GetMinCompletionsByWorkerThread());
|
||||
EXPECT_EQ(20, queue.GetNumberOfCompletedTasks());
|
||||
|
||||
// Same as last test, but with Broadcast().
|
||||
queue.ResetHistory();
|
||||
queue.SetTaskCount(20); // 2 tasks per process.
|
||||
queue.SetWorkTime(kThirtyMs);
|
||||
queue.SetAllowHelp(true);
|
||||
}
|
||||
queue.work_is_available()->Broadcast();
|
||||
// Wait to allow the 10 workers to get done.
|
||||
private_cv.TimedWait(kOneHundredMs); // Should take about 60 ms.
|
||||
|
||||
{
|
||||
AutoLock auto_lock(*queue.lock());
|
||||
EXPECT_EQ(10, queue.GetNumThreadsTakingAssignments());
|
||||
EXPECT_EQ(10, queue.GetNumThreadsCompletingTasks());
|
||||
EXPECT_EQ(0, queue.task_count());
|
||||
EXPECT_EQ(2, queue.GetMaxCompletionsByWorkerThread());
|
||||
EXPECT_EQ(2, queue.GetMinCompletionsByWorkerThread());
|
||||
EXPECT_EQ(20, queue.GetNumberOfCompletedTasks());
|
||||
|
||||
queue.SetShutdown();
|
||||
}
|
||||
queue.work_is_available()->Broadcast(); // Force check for shutdown.
|
||||
|
||||
SPIN_FOR_TIMEDELTA_OR_UNTIL_TRUE(TimeDelta::FromMinutes(1),
|
||||
queue.shutdown_task_count() == kThreadCount);
|
||||
Sleep(10); // Be sure they're all shutdown.
|
||||
}
|
||||
|
||||
TEST_F(ConditionVariableTest, LargeFastTaskTest) {
|
||||
const int kThreadCount = 200;
|
||||
WorkQueue queue(kThreadCount); // Start the threads.
|
||||
|
||||
Lock private_lock; // Used locally for master to wait.
|
||||
AutoLock private_held_lock(private_lock);
|
||||
ConditionVariable private_cv(&private_lock);
|
||||
|
||||
{
|
||||
AutoLock auto_lock(*queue.lock());
|
||||
while (!queue.EveryIdWasAllocated())
|
||||
queue.all_threads_have_ids()->Wait();
|
||||
}
|
||||
|
||||
// Wait a bit more to allow threads to reach their wait state.
|
||||
private_cv.TimedWait(kThirtyMs);
|
||||
|
||||
{
|
||||
// Since we have no tasks, all threads should be waiting by now.
|
||||
AutoLock auto_lock(*queue.lock());
|
||||
EXPECT_EQ(0, queue.GetNumThreadsTakingAssignments());
|
||||
EXPECT_EQ(0, queue.GetNumThreadsCompletingTasks());
|
||||
EXPECT_EQ(0, queue.task_count());
|
||||
EXPECT_EQ(0, queue.GetMaxCompletionsByWorkerThread());
|
||||
EXPECT_EQ(0, queue.GetMinCompletionsByWorkerThread());
|
||||
EXPECT_EQ(0, queue.GetNumberOfCompletedTasks());
|
||||
|
||||
// Set up to make all workers do (an average of) 20 tasks.
|
||||
queue.ResetHistory();
|
||||
queue.SetTaskCount(20 * kThreadCount);
|
||||
queue.SetWorkTime(kFortyFiveMs);
|
||||
queue.SetAllowHelp(false);
|
||||
}
|
||||
queue.work_is_available()->Broadcast(); // Start up all threads.
|
||||
// Wait until we've handed out all tasks.
|
||||
{
|
||||
AutoLock auto_lock(*queue.lock());
|
||||
while (queue.task_count() != 0)
|
||||
queue.no_more_tasks()->Wait();
|
||||
}
|
||||
|
||||
// Wait till the last of the tasks complete.
|
||||
// Don't bother to use locks: We may not get info in time... but we'll see it
|
||||
// eventually.
|
||||
SPIN_FOR_TIMEDELTA_OR_UNTIL_TRUE(TimeDelta::FromMinutes(1),
|
||||
20 * kThreadCount ==
|
||||
queue.GetNumberOfCompletedTasks());
|
||||
|
||||
{
|
||||
// With Broadcast(), every thread should have participated.
|
||||
// but with racing.. they may not all have done equal numbers of tasks.
|
||||
AutoLock auto_lock(*queue.lock());
|
||||
EXPECT_EQ(kThreadCount, queue.GetNumThreadsTakingAssignments());
|
||||
EXPECT_EQ(kThreadCount, queue.GetNumThreadsCompletingTasks());
|
||||
EXPECT_EQ(0, queue.task_count());
|
||||
EXPECT_LE(20, queue.GetMaxCompletionsByWorkerThread());
|
||||
EXPECT_EQ(20 * kThreadCount, queue.GetNumberOfCompletedTasks());
|
||||
|
||||
// Set up to make all workers do (an average of) 4 tasks.
|
||||
queue.ResetHistory();
|
||||
queue.SetTaskCount(kThreadCount * 4);
|
||||
queue.SetWorkTime(kFortyFiveMs);
|
||||
queue.SetAllowHelp(true); // Might outperform Broadcast().
|
||||
}
|
||||
queue.work_is_available()->Signal(); // Start up one thread.
|
||||
|
||||
// Wait until we've handed out all tasks
|
||||
{
|
||||
AutoLock auto_lock(*queue.lock());
|
||||
while (queue.task_count() != 0)
|
||||
queue.no_more_tasks()->Wait();
|
||||
}
|
||||
|
||||
// Wait till the last of the tasks complete.
|
||||
// Don't bother to use locks: We may not get info in time... but we'll see it
|
||||
// eventually.
|
||||
SPIN_FOR_TIMEDELTA_OR_UNTIL_TRUE(TimeDelta::FromMinutes(1),
|
||||
4 * kThreadCount ==
|
||||
queue.GetNumberOfCompletedTasks());
|
||||
|
||||
{
|
||||
// With Signal(), every thread should have participated.
|
||||
// but with racing.. they may not all have done four tasks.
|
||||
AutoLock auto_lock(*queue.lock());
|
||||
EXPECT_EQ(kThreadCount, queue.GetNumThreadsTakingAssignments());
|
||||
EXPECT_EQ(kThreadCount, queue.GetNumThreadsCompletingTasks());
|
||||
EXPECT_EQ(0, queue.task_count());
|
||||
EXPECT_LE(4, queue.GetMaxCompletionsByWorkerThread());
|
||||
EXPECT_EQ(4 * kThreadCount, queue.GetNumberOfCompletedTasks());
|
||||
|
||||
queue.SetShutdown();
|
||||
}
|
||||
queue.work_is_available()->Broadcast(); // Force check for shutdown.
|
||||
|
||||
// Wait for shutdows to complete.
|
||||
SPIN_FOR_TIMEDELTA_OR_UNTIL_TRUE(TimeDelta::FromMinutes(1),
|
||||
queue.shutdown_task_count() == kThreadCount);
|
||||
Sleep(10); // Be sure they're all shutdown.
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Finally we provide the implementation for the methods in the WorkQueue class.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
WorkQueue::WorkQueue(int thread_count)
|
||||
: lock_(),
|
||||
work_is_available_(&lock_),
|
||||
all_threads_have_ids_(&lock_),
|
||||
no_more_tasks_(&lock_),
|
||||
thread_count_(thread_count),
|
||||
handles_(new HANDLE[thread_count]),
|
||||
assignment_history_(thread_count),
|
||||
completion_history_(thread_count),
|
||||
thread_started_counter_(0),
|
||||
shutdown_task_count_(0),
|
||||
task_count_(0),
|
||||
allow_help_requests_(false),
|
||||
shutdown_(false) {
|
||||
EXPECT_GE(thread_count_, 1);
|
||||
ResetHistory();
|
||||
SetTaskCount(0);
|
||||
SetWorkTime(TimeDelta::FromMilliseconds(30));
|
||||
|
||||
for (int i = 0; i < thread_count_; ++i) {
|
||||
handles_[i] = CreateThread(NULL, // security.
|
||||
0, // <64K stack size.
|
||||
WorkerProcess, // Static function.
|
||||
reinterpret_cast<void*>(this),
|
||||
0, // Create running process.
|
||||
NULL); // OS version of thread id.
|
||||
EXPECT_NE(reinterpret_cast<void*>(NULL), handles_[i]);
|
||||
}
|
||||
}
|
||||
|
||||
WorkQueue::~WorkQueue() {
|
||||
{
|
||||
AutoLock auto_lock(lock_);
|
||||
SetShutdown();
|
||||
}
|
||||
work_is_available_.Broadcast(); // Tell them all to terminate.
|
||||
DWORD result = WaitForMultipleObjects(
|
||||
thread_count_,
|
||||
&handles_[0],
|
||||
true, // Wait for all
|
||||
10000); // Ten seconds max.
|
||||
|
||||
for (int i = 0; i < thread_count_; ++i) {
|
||||
int ret_value = CloseHandle(handles_[i]);
|
||||
CHECK(ret_value);
|
||||
handles_[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int WorkQueue::GetThreadId() {
|
||||
DCHECK(!EveryIdWasAllocated());
|
||||
return thread_started_counter_++; // Give out Unique IDs.
|
||||
}
|
||||
|
||||
bool WorkQueue::EveryIdWasAllocated() const {
|
||||
return thread_count_ == thread_started_counter_;
|
||||
}
|
||||
|
||||
TimeDelta WorkQueue::GetAnAssignment(int thread_id) {
|
||||
DCHECK_LT(0, task_count_);
|
||||
assignment_history_[thread_id]++;
|
||||
if (0 == --task_count_) {
|
||||
no_more_tasks_.Signal();
|
||||
}
|
||||
return worker_delay_;
|
||||
}
|
||||
|
||||
void WorkQueue::WorkIsCompleted(int thread_id) {
|
||||
completion_history_[thread_id]++;
|
||||
}
|
||||
|
||||
int WorkQueue::task_count() const {
|
||||
return task_count_;
|
||||
}
|
||||
|
||||
bool WorkQueue::allow_help_requests() const {
|
||||
return allow_help_requests_;
|
||||
}
|
||||
|
||||
bool WorkQueue::shutdown() const {
|
||||
return shutdown_;
|
||||
}
|
||||
|
||||
int WorkQueue::shutdown_task_count() const {
|
||||
return shutdown_task_count_;
|
||||
}
|
||||
|
||||
void WorkQueue::thread_shutting_down() {
|
||||
shutdown_task_count_++;
|
||||
}
|
||||
|
||||
Lock* WorkQueue::lock() {
|
||||
return &lock_;
|
||||
}
|
||||
|
||||
ConditionVariable* WorkQueue::work_is_available() {
|
||||
return &work_is_available_;
|
||||
}
|
||||
|
||||
ConditionVariable* WorkQueue::all_threads_have_ids() {
|
||||
return &all_threads_have_ids_;
|
||||
}
|
||||
|
||||
ConditionVariable* WorkQueue::no_more_tasks() {
|
||||
return &no_more_tasks_;
|
||||
}
|
||||
|
||||
void WorkQueue::ResetHistory() {
|
||||
for (int i = 0; i < thread_count_; ++i) {
|
||||
assignment_history_[i] = 0;
|
||||
completion_history_[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int WorkQueue::GetMinCompletionsByWorkerThread() const {
|
||||
int minumum = completion_history_[0];
|
||||
for (int i = 0; i < thread_count_; ++i)
|
||||
minumum = std::min(minumum, completion_history_[i]);
|
||||
return minumum;
|
||||
}
|
||||
|
||||
int WorkQueue::GetMaxCompletionsByWorkerThread() const {
|
||||
int maximum = completion_history_[0];
|
||||
for (int i = 0; i < thread_count_; ++i)
|
||||
maximum = std::max(maximum, completion_history_[i]);
|
||||
return maximum;
|
||||
}
|
||||
|
||||
int WorkQueue::GetNumThreadsTakingAssignments() const {
|
||||
int count = 0;
|
||||
for (int i = 0; i < thread_count_; ++i)
|
||||
if (assignment_history_[i])
|
||||
count++;
|
||||
return count;
|
||||
}
|
||||
|
||||
int WorkQueue::GetNumThreadsCompletingTasks() const {
|
||||
int count = 0;
|
||||
for (int i = 0; i < thread_count_; ++i)
|
||||
if (completion_history_[i])
|
||||
count++;
|
||||
return count;
|
||||
}
|
||||
|
||||
int WorkQueue::GetNumberOfCompletedTasks() const {
|
||||
int total = 0;
|
||||
for (int i = 0; i < thread_count_; ++i)
|
||||
total += completion_history_[i];
|
||||
return total;
|
||||
}
|
||||
|
||||
void WorkQueue::SetWorkTime(TimeDelta delay) {
|
||||
worker_delay_ = delay;
|
||||
}
|
||||
|
||||
void WorkQueue::SetTaskCount(int count) {
|
||||
task_count_ = count;
|
||||
}
|
||||
|
||||
void WorkQueue::SetAllowHelp(bool allow) {
|
||||
allow_help_requests_ = allow;
|
||||
}
|
||||
|
||||
void WorkQueue::SetShutdown() {
|
||||
shutdown_ = true;
|
||||
}
|
||||
|
||||
} // namespace
|
BIN
base/data/file_util_unittest/binary_file.bin
Normal file
BIN
base/data/file_util_unittest/binary_file_diff.bin
Normal file
BIN
base/data/file_util_unittest/binary_file_same.bin
Normal file
1
base/data/file_util_unittest/different.txt
Normal file
@ -0,0 +1 @@
|
||||
This file is different.
|
1
base/data/file_util_unittest/different_first.txt
Normal file
@ -0,0 +1 @@
|
||||
this file is the same.
|
1
base/data/file_util_unittest/different_last.txt
Normal file
@ -0,0 +1 @@
|
||||
This file is the same.
|
0
base/data/file_util_unittest/empty1.txt
Normal file
0
base/data/file_util_unittest/empty2.txt
Normal file
1
base/data/file_util_unittest/original.txt
Normal file
@ -0,0 +1 @@
|
||||
This file is the same.
|
1
base/data/file_util_unittest/same.txt
Normal file
@ -0,0 +1 @@
|
||||
This file is the same.
|
1
base/data/file_util_unittest/same_length.txt
Normal file
@ -0,0 +1 @@
|
||||
This file is not same.
|
1
base/data/file_util_unittest/shortened.txt
Normal file
@ -0,0 +1 @@
|
||||
This file is the
|
BIN
base/data/file_version_info_unittest/FileVersionInfoTest1.dll
Normal file
BIN
base/data/file_version_info_unittest/FileVersionInfoTest2.dll
Normal file
19
base/data/purify/base_unittests.exe.gtest.txt
Normal file
@ -0,0 +1,19 @@
|
||||
# this test causes Purify to get completely confused, aborting the test and
|
||||
# popping up 10 or more error dialogs
|
||||
StatsTableTest.MultipleProcesses
|
||||
|
||||
# see bug 1151158
|
||||
# causes purify to occasionally crash, possibly the same reason as 1110206 below
|
||||
StatsTableTest.MultipleThreads
|
||||
|
||||
# this test takes a really long time to run in Purify
|
||||
TimeTicks.Rollover
|
||||
|
||||
# see bug 1110206
|
||||
ConditionVariableTest.LargeFastTaskTest
|
||||
|
||||
# see bug 1150075
|
||||
MessageLoopTest.Crasher*
|
||||
|
||||
# see bug 1195707
|
||||
WMIUtilTest.*
|
97
base/data/purify/base_unittests.exe_MLK.txt
Normal file
@ -0,0 +1,97 @@
|
||||
std::D::_Allocate(unsigned int,char *) [base_unittests.exe]
|
||||
Alloc Location
|
||||
...
|
||||
base/check_handler_unittest.cc ThisFunctionAsserts(void)
|
||||
base/check_handler_unittest.cc CheckHandlerTest_TestMacroCheckFunc_Test::TestBody(void)
|
||||
testing/gtest/src/gtest.cc testing::Test::Run(void)
|
||||
^^^
|
||||
|
||||
std::_Mutex::_Mutex(void) [base_unittests.exe]
|
||||
Alloc Location
|
||||
...
|
||||
base/logging.cc logging::LogMessage::LogMessage(char const*,int,int)
|
||||
base/check_handler_unittest.cc ThisFunctionAsserts(void)
|
||||
base/check_handler_unittest.cc CheckHandlerTest_TestMacroCheckFunc_Test::TestBody(void)
|
||||
testing/gtest/src/gtest.cc testing::Test::Run(void)
|
||||
^^^
|
||||
|
||||
std::basic_streambuf<char,char_traits<char>::std>::basic_streambuf<char,char_traits<char>::std>(void) [base_unittests.exe]
|
||||
Alloc Location
|
||||
...
|
||||
base/logging.cc logging::LogMessage::LogMessage(char const*,int,int)
|
||||
base/check_handler_unittest.cc ThisFunctionAsserts(void)
|
||||
base/check_handler_unittest.cc CheckHandlerTest_TestMacroCheckFunc_Test::TestBody(void)
|
||||
testing/gtest/src/gtest.cc testing::Test::Run(void)
|
||||
^^^
|
||||
|
||||
std::ios_base::_Init(void) [base_unittests.exe]
|
||||
Alloc Location
|
||||
...
|
||||
base/logging.cc logging::LogMessage::LogMessage(char const*,int,int)
|
||||
base/check_handler_unittest.cc ThisFunctionAsserts(void)
|
||||
base/check_handler_unittest.cc CheckHandlerTest_TestMacroCheckFunc_Test::TestBody(void)
|
||||
testing/gtest/src/gtest.cc testing::Test::Run(void)
|
||||
^^^
|
||||
|
||||
std::D::_Allocate(unsigned int,char *) [base_unittests.exe]
|
||||
Alloc Location
|
||||
...
|
||||
base/logging.cc logging::LogMessage::~LogMessage(void)
|
||||
base/check_handler_unittest.cc ThisFunctionAsserts(void)
|
||||
base/check_handler_unittest.cc CheckHandlerTest_TestMacroCheckFunc_Test::TestBody(void)
|
||||
testing/gtest/src/gtest.cc testing::Test::Run(void)
|
||||
^^^
|
||||
|
||||
std::D::_Allocate(unsigned int,char *) [base_unittests.exe]
|
||||
Alloc Location
|
||||
...
|
||||
base/check_handler_unittest.cc SimpleTestClass::ThisMethodAsserts(void)
|
||||
base/check_handler_unittest.cc CheckHandlerTest_TestMacroCheckObj_Test::TestBody(void)
|
||||
testing/gtest/src/gtest.cc testing::Test::Run(void)
|
||||
^^^
|
||||
|
||||
std::_Mutex::_Mutex(void) [base_unittests.exe]
|
||||
Alloc Location
|
||||
...
|
||||
base/logging.cc logging::LogMessage::LogMessage(char const*,int,int)
|
||||
base/check_handler_unittest.cc SimpleTestClass::ThisMethodAsserts(void)
|
||||
base/check_handler_unittest.cc CheckHandlerTest_TestMacroCheckObj_Test::TestBody(void)
|
||||
testing/gtest/src/gtest.cc testing::Test::Run(void)
|
||||
^^^
|
||||
|
||||
std::basic_streambuf<char,char_traits<char>::std>::basic_streambuf<char,char_traits<char>::std>(void) [base_unittests.exe]
|
||||
Alloc Location
|
||||
...
|
||||
base/logging.cc logging::LogMessage::LogMessage(char const*,int,int)
|
||||
base/check_handler_unittest.cc SimpleTestClass::ThisMethodAsserts(void)
|
||||
base/check_handler_unittest.cc CheckHandlerTest_TestMacroCheckObj_Test::TestBody(void)
|
||||
testing/gtest/src/gtest.cc testing::Test::Run(void)
|
||||
^^^
|
||||
|
||||
std::ios_base::_Init(void) [base_unittests.exe]
|
||||
Alloc Location
|
||||
...
|
||||
base/logging.cc logging::LogMessage::LogMessage(char const*,int,int)
|
||||
base/check_handler_unittest.cc SimpleTestClass::ThisMethodAsserts(void)
|
||||
base/check_handler_unittest.cc CheckHandlerTest_TestMacroCheckObj_Test::TestBody(void)
|
||||
testing/gtest/src/gtest.cc testing::Test::Run(void)
|
||||
^^^
|
||||
|
||||
std::D::_Allocate(unsigned int,char *) [base_unittests.exe]
|
||||
Alloc Location
|
||||
...
|
||||
base/logging.cc logging::LogMessage::~LogMessage(void)
|
||||
base/check_handler_unittest.cc SimpleTestClass::ThisMethodAsserts(void)
|
||||
base/check_handler_unittest.cc CheckHandlerTest_TestMacroCheckObj_Test::TestBody(void)
|
||||
testing/gtest/src/gtest.cc testing::Test::Run(void)
|
||||
^^^
|
||||
|
||||
CoTaskMemAlloc [OLE32.DLL]
|
||||
Alloc Location
|
||||
...
|
||||
base/wmi_util.cc WMIUtil::CreateLocalConnection(bool)
|
||||
base/wmi_util.cc WMIProcessUtil::Launch(class std::basic_string const &,int *)
|
||||
base/wmi_util_unittest.cc WMIUtilTest_TestLaunchProcess_Test::TestBody(void)
|
||||
testing/gtest/src/gtest.cc testing::Test::Run(void)
|
||||
^^^
|
||||
|
8
base/data/purify/base_unittests.exe_MLK_flakey.txt
Normal file
@ -0,0 +1,8 @@
|
||||
CoTaskMemAlloc [OLE32.DLL]
|
||||
Alloc Location
|
||||
...
|
||||
base/wmi_util.cc WMIUtil::CreateLocalConnection(bool)
|
||||
base/wmi_util.cc WMIProcessUtil::Launch(class std::basic_string const &,int *)
|
||||
base/wmi_util_unittest.cc WMIUtilTest_TestLaunchProcess_Test::TestBody(void)
|
||||
testing/gtest/src/gtest.cc testing::Test::Run(void)
|
||||
^^^
|
93
base/data/purify/base_unittests.exe_MLK_ignore.txt
Normal file
@ -0,0 +1,93 @@
|
||||
# -----
|
||||
# Leaks in ::RaiseException, called when we log a fatal error. See bug 1078612.
|
||||
|
||||
std::strstreambuf::overflow(int) [base_unittests.exe]
|
||||
Alloc Location
|
||||
...
|
||||
base/check_handler_unittest.cc ThisFunctionAsserts(void)
|
||||
base/check_handler_unittest.cc CheckHandlerTest_TestMacroCheckFunc_Test::TestBody(void)
|
||||
testing/gtest/src/gtest.cc testing::Test::Run(void)
|
||||
^^^
|
||||
|
||||
std::_Mutex::_Mutex(void) [base_unittests.exe]
|
||||
Alloc Location
|
||||
...
|
||||
base/logging.cc logging::LogMessage::LogMessage(char const*,int,int)
|
||||
base/check_handler_unittest.cc ThisFunctionAsserts(void)
|
||||
base/check_handler_unittest.cc CheckHandlerTest_TestMacroCheckFunc_Test::TestBody(void)
|
||||
testing/gtest/src/gtest.cc testing::Test::Run(void)
|
||||
^^^
|
||||
|
||||
std::basic_streambuf<char,char_traits<char>::std>::basic_streambuf<char,char_traits<char>::std>(void) [base_unittests.exe]
|
||||
Alloc Location
|
||||
...
|
||||
base/logging.cc logging::LogMessage::LogMessage(char const*,int,int)
|
||||
base/check_handler_unittest.cc ThisFunctionAsserts(void)
|
||||
base/check_handler_unittest.cc CheckHandlerTest_TestMacroCheckFunc_Test::TestBody(void)
|
||||
testing/gtest/src/gtest.cc testing::Test::Run(void)
|
||||
^^^
|
||||
|
||||
std::ios_base::_Init(void) [base_unittests.exe]
|
||||
Alloc Location
|
||||
...
|
||||
base/logging.cc logging::LogMessage::LogMessage(char const*,int,int)
|
||||
base/check_handler_unittest.cc ThisFunctionAsserts(void)
|
||||
base/check_handler_unittest.cc CheckHandlerTest_TestMacroCheckFunc_Test::TestBody(void)
|
||||
testing/gtest/src/gtest.cc testing::Test::Run(void)
|
||||
^^^
|
||||
|
||||
std::D::_Allocate(unsigned int,char *) [base_unittests.exe]
|
||||
Alloc Location
|
||||
...
|
||||
base/logging.cc logging::LogMessage::~LogMessage(void)
|
||||
base/check_handler_unittest.cc ThisFunctionAsserts(void)
|
||||
base/check_handler_unittest.cc CheckHandlerTest_TestMacroCheckFunc_Test::TestBody(void)
|
||||
testing/gtest/src/gtest.cc testing::Test::Run(void)
|
||||
^^^
|
||||
|
||||
std::strstreambuf::overflow(int) [base_unittests.exe]
|
||||
Alloc Location
|
||||
...
|
||||
base/check_handler_unittest.cc SimpleTestClass::ThisMethodAsserts(void)
|
||||
base/check_handler_unittest.cc CheckHandlerTest_TestMacroCheckObj_Test::TestBody(void)
|
||||
testing/gtest/src/gtest.cc testing::Test::Run(void)
|
||||
^^^
|
||||
|
||||
std::_Mutex::_Mutex(void) [base_unittests.exe]
|
||||
Alloc Location
|
||||
...
|
||||
base/logging.cc logging::LogMessage::LogMessage(char const*,int,int)
|
||||
base/check_handler_unittest.cc SimpleTestClass::ThisMethodAsserts(void)
|
||||
base/check_handler_unittest.cc CheckHandlerTest_TestMacroCheckObj_Test::TestBody(void)
|
||||
testing/gtest/src/gtest.cc testing::Test::Run(void)
|
||||
^^^
|
||||
|
||||
std::basic_streambuf<char,char_traits<char>::std>::basic_streambuf<char,char_traits<char>::std>(void) [base_unittests.exe]
|
||||
Alloc Location
|
||||
...
|
||||
base/logging.cc logging::LogMessage::LogMessage(char const*,int,int)
|
||||
base/check_handler_unittest.cc SimpleTestClass::ThisMethodAsserts(void)
|
||||
base/check_handler_unittest.cc CheckHandlerTest_TestMacroCheckObj_Test::TestBody(void)
|
||||
testing/gtest/src/gtest.cc testing::Test::Run(void)
|
||||
^^^
|
||||
|
||||
std::ios_base::_Init(void) [base_unittests.exe]
|
||||
Alloc Location
|
||||
...
|
||||
base/logging.cc logging::LogMessage::LogMessage(char const*,int,int)
|
||||
base/check_handler_unittest.cc SimpleTestClass::ThisMethodAsserts(void)
|
||||
base/check_handler_unittest.cc CheckHandlerTest_TestMacroCheckObj_Test::TestBody(void)
|
||||
testing/gtest/src/gtest.cc testing::Test::Run(void)
|
||||
^^^
|
||||
|
||||
std::D::_Allocate(unsigned int,char *) [base_unittests.exe]
|
||||
Alloc Location
|
||||
...
|
||||
base/logging.cc logging::LogMessage::~LogMessage(void)
|
||||
base/check_handler_unittest.cc SimpleTestClass::ThisMethodAsserts(void)
|
||||
base/check_handler_unittest.cc CheckHandlerTest_TestMacroCheckObj_Test::TestBody(void)
|
||||
testing/gtest/src/gtest.cc testing::Test::Run(void)
|
||||
^^^
|
||||
|
||||
# End of leaks in ::RaiseException
|
||||
# -----
|
8
base/data/purify/base_unittests.exe_PAR_ignore.txt
Normal file
@ -0,0 +1,8 @@
|
||||
# Probably a Purify error. See bug 1076843.
|
||||
WideCharToMultiByte: Invalid size (0x27) for destination buffer.
|
||||
Error Location
|
||||
...
|
||||
base/file_util_unittest.cc FileUtilTest_ResolveShortcutTest_Test::TestBody(void)
|
||||
testing/gtest/src/gtest.cc testing::Test::Run(void)
|
||||
^^^
|
||||
|
0
base/data/purify/base_unittests.exe_UMR.txt
Normal file
BIN
base/data/vectorcanvastest/basicdrawing/00_pc_clean.png
Normal file
After ![]() (image error) Size: 289 B |
BIN
base/data/vectorcanvastest/basicdrawing/00_vc_clean.png
Normal file
After ![]() (image error) Size: 289 B |
BIN
base/data/vectorcanvastest/basicdrawing/01_pc_drawargb.png
Normal file
After ![]() (image error) Size: 289 B |
BIN
base/data/vectorcanvastest/basicdrawing/01_vc_drawargb.png
Normal file
After ![]() (image error) Size: 289 B |
BIN
base/data/vectorcanvastest/basicdrawing/02_pc_drawline_black.png
Normal file
After ![]() (image error) Size: 537 B |
BIN
base/data/vectorcanvastest/basicdrawing/02_vc_drawline_black.png
Normal file
After ![]() (image error) Size: 537 B |
BIN
base/data/vectorcanvastest/basicdrawing/03_pc_drawrect_green.png
Normal file
After ![]() (image error) Size: 417 B |
BIN
base/data/vectorcanvastest/basicdrawing/03_vc_drawrect_green.png
Normal file
After ![]() (image error) Size: 417 B |
BIN
base/data/vectorcanvastest/basicdrawing/04_pc_drawrect_noop.png
Normal file
After ![]() (image error) Size: 417 B |
BIN
base/data/vectorcanvastest/basicdrawing/04_vc_drawrect_noop.png
Normal file
After ![]() (image error) Size: 417 B |
BIN
base/data/vectorcanvastest/basicdrawing/05_pc_drawrect_noop.png
Normal file
After ![]() (image error) Size: 433 B |
BIN
base/data/vectorcanvastest/basicdrawing/05_vc_drawrect_noop.png
Normal file
After ![]() (image error) Size: 433 B |
After ![]() (image error) Size: 109 B |
After ![]() (image error) Size: 109 B |
After ![]() (image error) Size: 126 B |
After ![]() (image error) Size: 126 B |
BIN
base/data/vectorcanvastest/basicdrawing/08_pc_drawline_red.png
Normal file
After ![]() (image error) Size: 271 B |
BIN
base/data/vectorcanvastest/basicdrawing/08_vc_drawline_red.png
Normal file
After ![]() (image error) Size: 271 B |
BIN
base/data/vectorcanvastest/bitmaps/00_pc_opaque.png
Normal file
After ![]() (image error) Size: 5.0 KiB |
BIN
base/data/vectorcanvastest/bitmaps/00_vc_opaque.png
Normal file
After ![]() (image error) Size: 5.0 KiB |
BIN
base/data/vectorcanvastest/bitmaps/01_pc_alpha.png
Normal file
After ![]() (image error) Size: 2.6 KiB |
BIN
base/data/vectorcanvastest/bitmaps/01_vc_alpha.png
Normal file
After ![]() (image error) Size: 2.6 KiB |
BIN
base/data/vectorcanvastest/bitmaps/bitmap_alpha.png
Normal file
After ![]() (image error) Size: 422 B |
BIN
base/data/vectorcanvastest/bitmaps/bitmap_opaque.png
Normal file
After ![]() (image error) Size: 3.2 KiB |
BIN
base/data/vectorcanvastest/circles/00_pc_circle_stroke.png
Normal file
After ![]() (image error) Size: 383 B |
BIN
base/data/vectorcanvastest/circles/00_vc_circle_stroke.png
Normal file
After ![]() (image error) Size: 392 B |
BIN
base/data/vectorcanvastest/circles/01_pc_circle_fill.png
Normal file
After ![]() (image error) Size: 466 B |
BIN
base/data/vectorcanvastest/circles/01_vc_circle_fill.png
Normal file
After ![]() (image error) Size: 460 B |
BIN
base/data/vectorcanvastest/circles/02_pc_circle_over_strike.png
Normal file
After ![]() (image error) Size: 477 B |
BIN
base/data/vectorcanvastest/circles/02_vc_circle_over_strike.png
Normal file
After ![]() (image error) Size: 492 B |
After ![]() (image error) Size: 568 B |
After ![]() (image error) Size: 579 B |
BIN
base/data/vectorcanvastest/circles/04_pc_mixed_stroke.png
Normal file
After ![]() (image error) Size: 1.1 KiB |
BIN
base/data/vectorcanvastest/circles/04_vc_mixed_stroke.png
Normal file
After ![]() (image error) Size: 1.2 KiB |
BIN
base/data/vectorcanvastest/clippingclean/00_pc_clipped.png
Normal file
After ![]() (image error) Size: 1.3 KiB |
BIN
base/data/vectorcanvastest/clippingclean/00_vc_clipped.png
Normal file
After ![]() (image error) Size: 1.3 KiB |
BIN
base/data/vectorcanvastest/clippingclean/01_pc_unclipped.png
Normal file
After ![]() (image error) Size: 4.6 KiB |
BIN
base/data/vectorcanvastest/clippingclean/01_vc_unclipped.png
Normal file
After ![]() (image error) Size: 4.6 KiB |
BIN
base/data/vectorcanvastest/clippingcombined/00_pc_combined.png
Normal file
After ![]() (image error) Size: 1.3 KiB |
BIN
base/data/vectorcanvastest/clippingcombined/00_vc_combined.png
Normal file
After ![]() (image error) Size: 1.3 KiB |
BIN
base/data/vectorcanvastest/clippingintersect/00_pc_intersect.png
Normal file
After ![]() (image error) Size: 1.2 KiB |
BIN
base/data/vectorcanvastest/clippingintersect/00_vc_intersect.png
Normal file
After ![]() (image error) Size: 1.2 KiB |