// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// This file defines FileStream, a basic interface for reading and writing files
// synchronously or asynchronously with support for seeking to an offset.
// Note that even when used asynchronously, only one operation is supported at
// a time.
#ifndef NET_BASE_FILE_STREAM_H_
#define NET_BASE_FILE_STREAM_H_
#pragma once
#include "base/memory/scoped_ptr.h"
#include "base/platform_file.h"
#include "net/base/completion_callback.h"
class FilePath;
namespace net {
// TODO(darin): Move this to a more generic location.
// This explicit mapping matches both FILE_ on Windows and SEEK_ on Linux.
enum Whence {
FROM_BEGIN = 0,
FROM_CURRENT = 1,
FROM_END = 2
};
class FileStream {
public:
FileStream();
// Construct a FileStream with an existing file handle and opening flags.
// |file| is valid file handle.
// |flags| is a bitfield of base::PlatformFileFlags when the file handle was
// opened.
// The already opened file will not be automatically closed when FileStream
// is destructed.
FileStream(base::PlatformFile file, int flags);
~FileStream();
// Call this method to close the FileStream. It is OK to call Close
// multiple times. Redundant calls are ignored.
// Note that if there are any pending async operations, they'll be aborted.
void Close();
// Call this method to open the FileStream. The remaining methods
// cannot be used unless this method returns OK. If the file cannot be
// opened then an error code is returned.
// open_flags is a bitfield of base::PlatformFileFlags
int Open(const FilePath& path, int open_flags);
// Returns true if Open succeeded and Close has not been called.
bool IsOpen() const;
// Adjust the position from where data is read. Upon success, the stream
// position relative to the start of the file is returned. Otherwise, an
// error code is returned. It is not valid to call Seek while a Read call
// has a pending completion.
int64 Seek(Whence whence, int64 offset);
// Returns the number of bytes available to read from the current stream
// position until the end of the file. Otherwise, an error code is returned.
int64 Available();
// Call this method to read data from the current stream position. Up to
// buf_len bytes will be copied into buf. (In other words, partial reads are
// allowed.) Returns the number of bytes copied, 0 if at end-of-file, or an
// error code if the operation could not be performed.
//
// If opened with PLATFORM_FILE_ASYNC, then a non-null callback
// must be passed to this method. In asynchronous mode, if the read could
// not complete synchronously, then ERR_IO_PENDING is returned, and the
// callback will be notified on the current thread (via the MessageLoop) when
// the read has completed.
//
// In the case of an asychronous read, the memory pointed to by |buf| must
// remain valid until the callback is notified. However, it is valid to
// destroy or close the file stream while there is an asynchronous read in
// progress. That will cancel the read and allow the buffer to be freed.
//
// This method should not be called if the stream was opened WRITE_ONLY.
//
// You can pass NULL as the callback for synchronous I/O.
int Read(char* buf, int buf_len, CompletionCallback* callback);
// Performs the same as Read, but ensures that exactly buf_len bytes
// are copied into buf. A partial read may occur, but only as a result of
// end-of-file or fatal error. Returns the number of bytes copied into buf,
// 0 if at end-of-file and no bytes have been read into buf yet,
// or an error code if the operation could not be performed.
int ReadUntilComplete(char *buf, int buf_len);
// Call this method to write data at the current stream position. Up to
// buf_len bytes will be written from buf. (In other words, partial writes are
// allowed.) Returns the number of bytes written, or an error code if the
// operation could not be performed.
//
// If opened with PLATFORM_FILE_ASYNC, then a non-null callback
// must be passed to this method. In asynchronous mode, if the write could
// not complete synchronously, then ERR_IO_PENDING is returned, and the
// callback will be notified on the current thread (via the MessageLoop) when
// the write has completed.
//
// In the case of an asychronous write, the memory pointed to by |buf| must
// remain valid until the callback is notified. However, it is valid to
// destroy or close the file stream while there is an asynchronous write in
// progress. That will cancel the write and allow the buffer to be freed.
//
// This method should not be called if the stream was opened READ_ONLY.
//
// You can pass NULL as the callback for synchronous I/O.
int Write(const char* buf, int buf_len, CompletionCallback* callback);
// Truncates the file to be |bytes| length. This is only valid for writable
// files. After truncation the file stream is positioned at |bytes|. The new
// position is retured, or a value < 0 on error.
// WARNING: one may not truncate a file beyond its current length on any
// platform with this call.
int64 Truncate(int64 bytes);
// Forces out a filesystem sync on this file to make sure that the file was
// written out to disk and is not currently sitting in the buffer. This does
// not have to be called, it just forces one to happen at the time of
// calling.
//
/// Returns an error code if the operation could not be performed.
//
// This method should not be called if the stream was opened READ_ONLY.
int Flush();
private:
class AsyncContext;
friend class AsyncContext;
// This member is used to support asynchronous reads. It is non-null when
// the FileStream was opened with PLATFORM_FILE_ASYNC.
scoped_ptr<AsyncContext> async_context_;
base::PlatformFile file_;
int open_flags_;
bool auto_closed_;
DISALLOW_COPY_AND_ASSIGN(FileStream);
};
} // namespace net
#endif // NET_BASE_FILE_STREAM_H_