summaryrefslogtreecommitdiffstats
path: root/base
diff options
context:
space:
mode:
authorloislo@chromium.org <loislo@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-04-29 12:57:10 +0000
committerloislo@chromium.org <loislo@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-04-29 12:57:10 +0000
commit891128f4847bfb32e10604ced9a3b93c0272a80d (patch)
tree001b3799eda821b47e2efa01a8412a194377fc8b /base
parent19bacfe41d03eede36a797ea37e8c8c2a477e995 (diff)
downloadchromium_src-891128f4847bfb32e10604ced9a3b93c0272a80d.zip
chromium_src-891128f4847bfb32e10604ced9a3b93c0272a80d.tar.gz
chromium_src-891128f4847bfb32e10604ced9a3b93c0272a80d.tar.bz2
AppendToFile implementation.
DevTools wants to save very big files like HeapSnapshots. It is not possible at the moment because the file can be about ~6Gb. BUG=none TEST=FileUtilTest.AppendToFile Review URL: http://codereview.chromium.org/10263003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@134492 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base')
-rw-r--r--base/file_util.h4
-rw-r--r--base/file_util_posix.cc12
-rw-r--r--base/file_util_unittest.cc28
-rw-r--r--base/file_util_win.cc32
4 files changed, 76 insertions, 0 deletions
diff --git a/base/file_util.h b/base/file_util.h
index b6e634d..1eac1ca 100644
--- a/base/file_util.h
+++ b/base/file_util.h
@@ -378,6 +378,10 @@ BASE_EXPORT int WriteFile(const FilePath& filename, const char* data, int size);
// Append the data to |fd|. Does not close |fd| when done.
BASE_EXPORT int WriteFileDescriptor(const int fd, const char* data, int size);
#endif
+// Append the given buffer into the file. Returns the number of bytes written,
+// or -1 on error.
+BASE_EXPORT int AppendToFile(const FilePath& filename,
+ const char* data, int size);
// Gets the current working directory for the process.
BASE_EXPORT bool GetCurrentDirectory(FilePath* path);
diff --git a/base/file_util_posix.cc b/base/file_util_posix.cc
index 00c96fd..f1113d5 100644
--- a/base/file_util_posix.cc
+++ b/base/file_util_posix.cc
@@ -664,6 +664,18 @@ int WriteFileDescriptor(const int fd, const char* data, int size) {
return bytes_written_total;
}
+int AppendToFile(const FilePath& filename, const char* data, int size) {
+ base::ThreadRestrictions::AssertIOAllowed();
+ int fd = HANDLE_EINTR(open(filename.value().c_str(), O_WRONLY | O_APPEND));
+ if (fd < 0)
+ return -1;
+
+ int bytes_written = WriteFileDescriptor(fd, data, size);
+ if (int ret = HANDLE_EINTR(close(fd)) < 0)
+ return ret;
+ return bytes_written;
+}
+
// Gets the current working directory for the process.
bool GetCurrentDirectory(FilePath* dir) {
// getcwd can return ENOENT, which implies it checks against the disk.
diff --git a/base/file_util_unittest.cc b/base/file_util_unittest.cc
index 30db82c..ea8918b 100644
--- a/base/file_util_unittest.cc
+++ b/base/file_util_unittest.cc
@@ -1790,6 +1790,34 @@ TEST_F(FileUtilTest, FileEnumeratorTest) {
// (we don't care what).
}
+TEST_F(FileUtilTest, AppendToFile) {
+ FilePath data_dir =
+ temp_dir_.path().Append(FILE_PATH_LITERAL("FilePathTest"));
+
+ // Create a fresh, empty copy of this directory.
+ if (file_util::PathExists(data_dir)) {
+ ASSERT_TRUE(file_util::Delete(data_dir, true));
+ }
+ ASSERT_TRUE(file_util::CreateDirectory(data_dir));
+
+ // Create a fresh, empty copy of this directory.
+ if (file_util::PathExists(data_dir)) {
+ ASSERT_TRUE(file_util::Delete(data_dir, true));
+ }
+ ASSERT_TRUE(file_util::CreateDirectory(data_dir));
+ FilePath foobar(data_dir.Append(FILE_PATH_LITERAL("foobar.txt")));
+
+ std::string data("hello");
+ EXPECT_EQ(-1, file_util::AppendToFile(foobar, data.c_str(), data.length()));
+ EXPECT_EQ(static_cast<int>(data.length()),
+ file_util::WriteFile(foobar, data.c_str(), data.length()));
+ EXPECT_EQ(static_cast<int>(data.length()),
+ file_util::AppendToFile(foobar, data.c_str(), data.length()));
+
+ const std::wstring read_content = ReadTextFile(foobar);
+ EXPECT_EQ(L"hellohello", read_content);
+}
+
TEST_F(FileUtilTest, Contains) {
FilePath data_dir =
temp_dir_.path().Append(FILE_PATH_LITERAL("FilePathTest"));
diff --git a/base/file_util_win.cc b/base/file_util_win.cc
index 7d28f5c..e9f9def 100644
--- a/base/file_util_win.cc
+++ b/base/file_util_win.cc
@@ -722,6 +722,38 @@ int WriteFile(const FilePath& filename, const char* data, int size) {
return -1;
}
+int AppendToFile(const FilePath& filename, const char* data, int size) {
+ base::ThreadRestrictions::AssertIOAllowed();
+ base::win::ScopedHandle file(CreateFile(filename.value().c_str(),
+ FILE_APPEND_DATA,
+ 0,
+ NULL,
+ OPEN_EXISTING,
+ 0,
+ NULL));
+ if (!file) {
+ DLOG(WARNING) << "CreateFile failed for path " << filename.value()
+ << " error code=" << GetLastError();
+ return -1;
+ }
+
+ DWORD written;
+ BOOL result = ::WriteFile(file, data, size, &written, NULL);
+ if (result && static_cast<int>(written) == size)
+ return written;
+
+ if (!result) {
+ // WriteFile failed.
+ DLOG(WARNING) << "writing file " << filename.value()
+ << " failed, error code=" << GetLastError();
+ } else {
+ // Didn't write all the bytes.
+ DLOG(WARNING) << "wrote" << written << " bytes to "
+ << filename.value() << " expected " << size;
+ }
+ return -1;
+}
+
// Gets the current working directory for the process.
bool GetCurrentDirectory(FilePath* dir) {
base::ThreadRestrictions::AssertIOAllowed();