1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "components/drive/file_system/truncate_operation.h"
8 #include "base/callback_helpers.h"
9 #include "base/files/file.h"
10 #include "base/files/file_path.h"
11 #include "base/logging.h"
12 #include "base/sequenced_task_runner.h"
13 #include "base/task_runner_util.h"
14 #include "base/thread_task_runner_handle.h"
15 #include "components/drive/drive.pb.h"
16 #include "components/drive/file_cache.h"
17 #include "components/drive/file_errors.h"
18 #include "components/drive/file_system/download_operation.h"
19 #include "components/drive/file_system/operation_delegate.h"
20 #include "components/drive/job_scheduler.h"
23 namespace file_system
{
26 // Truncates the local file at |local_cache_path| to the |length| bytes,
27 // then marks the resource is dirty on |cache|.
28 FileError
TruncateOnBlockingPool(internal::ResourceMetadata
* metadata
,
29 internal::FileCache
* cache
,
30 const std::string
& local_id
,
31 const base::FilePath
& local_cache_path
,
36 scoped_ptr
<base::ScopedClosureRunner
> file_closer
;
37 FileError error
= cache
->OpenForWrite(local_id
, &file_closer
);
38 if (error
!= FILE_ERROR_OK
)
41 base::File
file(local_cache_path
,
42 base::File::FLAG_OPEN
| base::File::FLAG_WRITE
);
44 return FILE_ERROR_FAILED
;
46 if (!file
.SetLength(length
))
47 return FILE_ERROR_FAILED
;
54 TruncateOperation::TruncateOperation(
55 base::SequencedTaskRunner
* blocking_task_runner
,
56 OperationDelegate
* delegate
,
57 JobScheduler
* scheduler
,
58 internal::ResourceMetadata
* metadata
,
59 internal::FileCache
* cache
,
60 const base::FilePath
& temporary_file_directory
)
61 : blocking_task_runner_(blocking_task_runner
),
65 download_operation_(new DownloadOperation(blocking_task_runner
,
70 temporary_file_directory
)),
71 weak_ptr_factory_(this) {
74 TruncateOperation::~TruncateOperation() {
77 void TruncateOperation::Truncate(const base::FilePath
& file_path
,
79 const FileOperationCallback
& callback
) {
80 DCHECK(thread_checker_
.CalledOnValidThread());
81 DCHECK(!callback
.is_null());
84 base::ThreadTaskRunnerHandle::Get()->PostTask(
86 base::Bind(callback
, FILE_ERROR_INVALID_OPERATION
));
90 // TODO(kinaba): http://crbug.com/132780.
91 // Optimize the cases for small |length|, at least for |length| == 0.
92 download_operation_
->EnsureFileDownloadedByPath(
94 ClientContext(USER_INITIATED
),
95 GetFileContentInitializedCallback(),
96 google_apis::GetContentCallback(),
97 base::Bind(&TruncateOperation::TruncateAfterEnsureFileDownloadedByPath
,
98 weak_ptr_factory_
.GetWeakPtr(), length
, callback
));
101 void TruncateOperation::TruncateAfterEnsureFileDownloadedByPath(
103 const FileOperationCallback
& callback
,
105 const base::FilePath
& local_file_path
,
106 scoped_ptr
<ResourceEntry
> entry
) {
107 DCHECK(thread_checker_
.CalledOnValidThread());
108 DCHECK(!callback
.is_null());
110 if (error
!= FILE_ERROR_OK
) {
115 DCHECK(entry
->has_file_specific_info());
117 if (entry
->file_specific_info().is_hosted_document()) {
118 callback
.Run(FILE_ERROR_INVALID_OPERATION
);
122 base::PostTaskAndReplyWithResult(
123 blocking_task_runner_
.get(),
125 base::Bind(&TruncateOnBlockingPool
,
126 metadata_
, cache_
, entry
->local_id(), local_file_path
, length
),
128 &TruncateOperation::TruncateAfterTruncateOnBlockingPool
,
129 weak_ptr_factory_
.GetWeakPtr(), entry
->local_id(), callback
));
132 void TruncateOperation::TruncateAfterTruncateOnBlockingPool(
133 const std::string
& local_id
,
134 const FileOperationCallback
& callback
,
136 DCHECK(thread_checker_
.CalledOnValidThread());
137 DCHECK(!callback
.is_null());
139 delegate_
->OnEntryUpdatedByOperation(ClientContext(USER_INITIATED
), local_id
);
144 } // namespace file_system