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_context.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <errno.h>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind_helpers.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/location.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/histogram.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/posix/eintr_wrapper.h"
18010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "base/task_runner.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/task_runner_util.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/io_buffer.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_errors.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net {
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
250529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochFileStream::Context::Context(const scoped_refptr<base::TaskRunner>& task_runner)
26c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    : async_in_progress_(false),
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      orphaned_(false),
287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      task_runner_(task_runner) {
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)FileStream::Context::Context(base::File file,
327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                             const scoped_refptr<base::TaskRunner>& task_runner)
3323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    : file_(file.Pass()),
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      async_in_progress_(false),
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      orphaned_(false),
367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      task_runner_(task_runner) {
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FileStream::Context::~Context() {
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42116680a4aac90f2aa7413d9095a592090648e557Ben Murdochint FileStream::Context::Read(IOBuffer* in_buf,
43116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                              int buf_len,
44116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                              const CompletionCallback& callback) {
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!async_in_progress_);
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<IOBuffer> buf = in_buf;
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const bool posted = base::PostTaskAndReplyWithResult(
497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      task_runner_.get(),
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE,
51868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      base::Bind(&Context::ReadFileImpl, base::Unretained(this), buf, buf_len),
520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      base::Bind(&Context::OnAsyncCompleted,
53868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                 base::Unretained(this),
540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 IntToInt64(callback)));
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(posted);
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  async_in_progress_ = true;
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ERR_IO_PENDING;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61116680a4aac90f2aa7413d9095a592090648e557Ben Murdochint FileStream::Context::Write(IOBuffer* in_buf,
62116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                               int buf_len,
63116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                               const CompletionCallback& callback) {
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!async_in_progress_);
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<IOBuffer> buf = in_buf;
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const bool posted = base::PostTaskAndReplyWithResult(
687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      task_runner_.get(),
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE,
70868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      base::Bind(&Context::WriteFileImpl, base::Unretained(this), buf, buf_len),
710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      base::Bind(&Context::OnAsyncCompleted,
72868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                 base::Unretained(this),
730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 IntToInt64(callback)));
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(posted);
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  async_in_progress_ = true;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ERR_IO_PENDING;
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80116680a4aac90f2aa7413d9095a592090648e557Ben MurdochFileStream::Context::IOResult FileStream::Context::SeekFileImpl(
81116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    base::File::Whence whence,
82116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    int64 offset) {
83116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  int64 res = file_.Seek(whence, offset);
84116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (res == -1)
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return IOResult::FromOSError(errno);
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return IOResult(res, 0);
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
90116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid FileStream::Context::OnFileOpened() {
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)FileStream::Context::IOResult FileStream::Context::ReadFileImpl(
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_refptr<IOBuffer> buf,
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int buf_len) {
96116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  int res = file_.ReadAtCurrentPosNoBestEffort(buf->data(), buf_len);
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (res == -1)
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return IOResult::FromOSError(errno);
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return IOResult(res, 0);
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)FileStream::Context::IOResult FileStream::Context::WriteFileImpl(
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_refptr<IOBuffer> buf,
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int buf_len) {
106116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  int res = file_.WriteAtCurrentPosNoBestEffort(buf->data(), buf_len);
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (res == -1)
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return IOResult::FromOSError(errno);
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return IOResult(res, 0);
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace net
114