file_stream.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/file_stream.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/location.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/message_loop_proxy.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/task_runner_util.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread_restrictions.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/worker_pool.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/file_stream_context.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/file_stream_net_log_parameters.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_errors.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net {
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FileStream::FileStream(NetLog* net_log)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      /* To allow never opened stream to be destroyed on any thread we set flags
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         as if stream was opened asynchronously. */
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : open_flags_(base::PLATFORM_FILE_ASYNC),
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bound_net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_FILESTREAM)),
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      context_(new Context(bound_net_log_)) {
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bound_net_log_.BeginEvent(NetLog::TYPE_FILE_STREAM_ALIVE);
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FileStream::FileStream(base::PlatformFile file, int flags, NetLog* net_log)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : open_flags_(flags),
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bound_net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_FILESTREAM)),
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      context_(new Context(file, bound_net_log_, open_flags_)) {
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bound_net_log_.BeginEvent(NetLog::TYPE_FILE_STREAM_ALIVE);
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FileStream::~FileStream() {
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!is_async()) {
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::ThreadRestrictions::AssertIOAllowed();
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    context_->CloseSync();
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    context_.reset();
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    context_.release()->Orphan();
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bound_net_log_.EndEvent(NetLog::TYPE_FILE_STREAM_ALIVE);
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int FileStream::Open(const FilePath& path, int open_flags,
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     const CompletionCallback& callback) {
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (IsOpen()) {
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DLOG(FATAL) << "File is already open!";
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ERR_UNEXPECTED;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  open_flags_ = open_flags;
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(is_async());
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  context_->OpenAsync(path, open_flags, callback);
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ERR_IO_PENDING;
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int FileStream::OpenSync(const FilePath& path, int open_flags) {
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::ThreadRestrictions::AssertIOAllowed();
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (IsOpen()) {
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DLOG(FATAL) << "File is already open!";
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ERR_UNEXPECTED;
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  open_flags_ = open_flags;
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(satorux): Put a DCHECK once all async clients are migrated
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to use Open(). crbug.com/114783
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // DCHECK(!is_async());
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return context_->OpenSync(path, open_flags_);
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool FileStream::IsOpen() const {
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return context_->file() != base::kInvalidPlatformFileValue;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int FileStream::Seek(Whence whence,
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     int64 offset,
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     const Int64CompletionCallback& callback) {
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!IsOpen())
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ERR_UNEXPECTED;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure we're async.
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(is_async());
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  context_->SeekAsync(whence, offset, callback);
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ERR_IO_PENDING;
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int64 FileStream::SeekSync(Whence whence, int64 offset) {
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::ThreadRestrictions::AssertIOAllowed();
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!IsOpen())
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ERR_UNEXPECTED;
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If we're in async, make sure we don't have a request in flight.
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!is_async() || !context_->async_in_progress());
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return context_->SeekSync(whence, offset);
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int64 FileStream::Available() {
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::ThreadRestrictions::AssertIOAllowed();
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!IsOpen())
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ERR_UNEXPECTED;
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 cur_pos = SeekSync(FROM_CURRENT, 0);
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (cur_pos < 0)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return cur_pos;
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 size = context_->GetFileSize();
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (size < 0)
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return size;
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_GT(size, cur_pos);
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return size - cur_pos;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int FileStream::Read(IOBuffer* buf,
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     int buf_len,
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     const CompletionCallback& callback) {
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!IsOpen())
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ERR_UNEXPECTED;
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // read(..., 0) will return 0, which indicates end-of-file.
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_GT(buf_len, 0);
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(open_flags_ & base::PLATFORM_FILE_READ);
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(is_async());
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return context_->ReadAsync(buf, buf_len, callback);
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int FileStream::ReadSync(char* buf, int buf_len) {
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::ThreadRestrictions::AssertIOAllowed();
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!IsOpen())
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ERR_UNEXPECTED;
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!is_async());
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // read(..., 0) will return 0, which indicates end-of-file.
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_GT(buf_len, 0);
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(open_flags_ & base::PLATFORM_FILE_READ);
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return context_->ReadSync(buf, buf_len);
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int FileStream::ReadUntilComplete(char *buf, int buf_len) {
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::ThreadRestrictions::AssertIOAllowed();
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int to_read = buf_len;
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int bytes_total = 0;
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  do {
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int bytes_read = ReadSync(buf, to_read);
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (bytes_read <= 0) {
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (bytes_total == 0)
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return bytes_read;
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return bytes_total;
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bytes_total += bytes_read;
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    buf += bytes_read;
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    to_read -= bytes_read;
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } while (bytes_total < buf_len);
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return bytes_total;
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int FileStream::Write(IOBuffer* buf,
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      int buf_len,
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      const CompletionCallback& callback) {
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!IsOpen())
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ERR_UNEXPECTED;
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(is_async());
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(open_flags_ & base::PLATFORM_FILE_WRITE);
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // write(..., 0) will return 0, which indicates end-of-file.
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_GT(buf_len, 0);
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return context_->WriteAsync(buf, buf_len, callback);
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int FileStream::WriteSync(const char* buf, int buf_len) {
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::ThreadRestrictions::AssertIOAllowed();
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!IsOpen())
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ERR_UNEXPECTED;
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!is_async());
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(open_flags_ & base::PLATFORM_FILE_WRITE);
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // write(..., 0) will return 0, which indicates end-of-file.
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_GT(buf_len, 0);
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return context_->WriteSync(buf, buf_len);
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int64 FileStream::Truncate(int64 bytes) {
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::ThreadRestrictions::AssertIOAllowed();
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!IsOpen())
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ERR_UNEXPECTED;
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We'd better be open for writing.
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(open_flags_ & base::PLATFORM_FILE_WRITE);
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Seek to the position to truncate from.
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 seek_position = SeekSync(FROM_BEGIN, bytes);
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (seek_position != bytes)
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ERR_UNEXPECTED;
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // And truncate the file.
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return context_->Truncate(bytes);
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int FileStream::Flush(const CompletionCallback& callback) {
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!IsOpen())
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ERR_UNEXPECTED;
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(open_flags_ & base::PLATFORM_FILE_WRITE);
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure we're async.
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(is_async());
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  context_->FlushAsync(callback);
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ERR_IO_PENDING;
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int FileStream::FlushSync() {
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::ThreadRestrictions::AssertIOAllowed();
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!IsOpen())
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ERR_UNEXPECTED;
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(open_flags_ & base::PLATFORM_FILE_WRITE);
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return context_->FlushSync();
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileStream::EnableErrorStatistics() {
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  context_->set_record_uma(true);
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileStream::SetBoundNetLogSource(const BoundNetLog& owner_bound_net_log) {
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if ((owner_bound_net_log.source().id == NetLog::Source::kInvalidId) &&
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (bound_net_log_.source().id == NetLog::Source::kInvalidId)) {
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Both |BoundNetLog|s are invalid.
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Should never connect to itself.
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_NE(bound_net_log_.source().id, owner_bound_net_log.source().id);
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bound_net_log_.AddEvent(NetLog::TYPE_FILE_STREAM_BOUND_TO_OWNER,
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      owner_bound_net_log.source().ToEventParametersCallback());
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  owner_bound_net_log.AddEvent(NetLog::TYPE_FILE_STREAM_SOURCE,
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bound_net_log_.source().ToEventParametersCallback());
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::PlatformFile FileStream::GetPlatformFileForTesting() {
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return context_->file();
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace net
265