mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-19 18:45:52 +00:00
243 lines
8.0 KiB
C++
243 lines
8.0 KiB
C++
//------------------------------------------------------------------------------
|
|
/*
|
|
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
|
|
Portions of this file are from JUCE.
|
|
Copyright (c) 2013 - Raw Material Software Ltd.
|
|
Please visit http://www.juce.com
|
|
|
|
Permission to use, copy, modify, and/or distribute this software for any
|
|
purpose with or without fee is hereby granted, provided that the above
|
|
copyright notice and this permission notice appear in all copies.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
*/
|
|
//==============================================================================
|
|
|
|
#ifndef BEAST_RANDOMACCESSFILE_H_INCLUDED
|
|
#define BEAST_RANDOMACCESSFILE_H_INCLUDED
|
|
|
|
#include "../misc/beast_Result.h"
|
|
|
|
/** Provides random access reading and writing to an operating system file.
|
|
|
|
This class wraps the underlying native operating system routines for
|
|
opening and closing a file for reading and/or writing, seeking within
|
|
the file, and performing read and write operations. There are also methods
|
|
provided for obtaining an input or output stream which will work with
|
|
the file.
|
|
|
|
Writes are batched using an internal buffer. The buffer is flushed when
|
|
it fills, the current position is manually changed, or the file
|
|
is closed. It is also possible to explicitly flush the buffer.
|
|
|
|
@note All files are opened in binary mode. No text newline conversions
|
|
are performed.
|
|
|
|
@see FileInputStream, FileOutputStream
|
|
*/
|
|
class BEAST_API RandomAccessFile : Uncopyable, LeakChecked <RandomAccessFile>
|
|
{
|
|
public:
|
|
/** The type of an FileOffset.
|
|
|
|
This can be useful when writing templates.
|
|
*/
|
|
typedef int64 FileOffset;
|
|
|
|
/** The type of a byte count.
|
|
|
|
This can be useful when writing templates.
|
|
*/
|
|
typedef size_t ByteCount;
|
|
|
|
/** The access mode.
|
|
|
|
@see open
|
|
*/
|
|
enum Mode
|
|
{
|
|
readOnly,
|
|
readWrite
|
|
};
|
|
|
|
//==============================================================================
|
|
/** Creates an unopened file object.
|
|
|
|
@see open, isOpen
|
|
*/
|
|
explicit RandomAccessFile (int bufferSizeToUse = 16384) noexcept;
|
|
|
|
/** Destroy the file object.
|
|
|
|
If the operating system file is open it will be closed.
|
|
*/
|
|
~RandomAccessFile ();
|
|
|
|
/** Determine if a file is open.
|
|
|
|
@return `true` if the operating system file is open.
|
|
*/
|
|
bool isOpen () const noexcept { return fileHandle != nullptr; }
|
|
|
|
/** Opens a file object.
|
|
|
|
The file is opened with the specified permissions. The initial
|
|
position is set to the beginning of the file.
|
|
|
|
@note If a file is already open, it will be closed first.
|
|
|
|
@param path The path to the file
|
|
@param mode The access permissions
|
|
@return An indication of the success of the operation.
|
|
|
|
@see Mode
|
|
*/
|
|
Result open (File const& path, Mode mode);
|
|
|
|
/** Closes the file object.
|
|
|
|
Any data that needs to be flushed will be written before the file is closed.
|
|
|
|
@note If no file is opened, this call does nothing.
|
|
*/
|
|
void close ();
|
|
|
|
/** Retrieve the @ref File associated with this object.
|
|
|
|
@return The associated @ref File.
|
|
*/
|
|
File const& getFile () const noexcept { return file; }
|
|
|
|
/** Get the current position.
|
|
|
|
The next read or write will take place from here.
|
|
|
|
@return The current position, as an absolute byte FileOffset from the begining.
|
|
*/
|
|
FileOffset getPosition () const noexcept { return currentPosition; }
|
|
|
|
/** Set the current position.
|
|
|
|
The next read or write will take place at this location.
|
|
|
|
@param newPosition The byte FileOffset from the beginning of the file to move to.
|
|
|
|
@return `true` if the operation was successful.
|
|
*/
|
|
Result setPosition (FileOffset newPosition);
|
|
|
|
/** Read data at the current position.
|
|
|
|
The caller is responsible for making sure that the memory pointed to
|
|
by `buffer` is at least as large as `bytesToRead`.
|
|
|
|
@note The file must have been opened with read permission.
|
|
|
|
@param buffer The memory to store the incoming data
|
|
@param numBytes The number of bytes to read.
|
|
@param pActualAmount Pointer to store the actual amount read, or `nullptr`.
|
|
|
|
@return `true` if all the bytes were read.
|
|
*/
|
|
Result read (void* buffer, ByteCount numBytes, ByteCount* pActualAmount = 0);
|
|
|
|
/** Write data at the current position.
|
|
|
|
The current position is advanced past the data written. If data is
|
|
written past the end of the file, the file size is increased on disk.
|
|
|
|
The caller is responsible for making sure that the memory pointed to
|
|
by `buffer` is at least as large as `bytesToWrite`.
|
|
|
|
@note The file must have been opened with write permission.
|
|
|
|
@param data A pointer to the data buffer to write to the file.
|
|
@param numBytes The number of bytes to write.
|
|
@param pActualAmount Pointer to store the actual amount written, or `nullptr`.
|
|
|
|
@return `true` if all the data was written.
|
|
*/
|
|
Result write (const void* data, ByteCount numBytes, ByteCount* pActualAmount = 0);
|
|
|
|
/** Truncate the file at the current position.
|
|
*/
|
|
Result truncate ();
|
|
|
|
/** Flush the output buffers.
|
|
|
|
This calls the operating system to make sure all data has been written.
|
|
*/
|
|
Result flush();
|
|
|
|
//==============================================================================
|
|
private:
|
|
Result flushBuffer ();
|
|
|
|
// Some of these these methods are implemented natively on
|
|
// the corresponding platform.
|
|
//
|
|
// See beast_posix_SharedCode.h and beast_win32_Files.cpp
|
|
Result nativeOpen (File const& path, Mode mode);
|
|
void nativeClose ();
|
|
Result nativeSetPosition (FileOffset newPosition);
|
|
Result nativeRead (void* buffer, ByteCount numBytes, ByteCount* pActualAmount = 0);
|
|
Result nativeWrite (const void* data, ByteCount numBytes, ByteCount* pActualAmount = 0);
|
|
Result nativeTruncate ();
|
|
Result nativeFlush ();
|
|
|
|
private:
|
|
File file;
|
|
void* fileHandle;
|
|
FileOffset currentPosition;
|
|
ByteCount const bufferSize;
|
|
ByteCount bytesInBuffer;
|
|
HeapBlock <char> writeBuffer;
|
|
};
|
|
|
|
class BEAST_API RandomAccessFileInputStream : public InputStream
|
|
{
|
|
public:
|
|
explicit RandomAccessFileInputStream (RandomAccessFile& file) : m_file (file) { }
|
|
|
|
int64 getTotalLength() { return m_file.getFile ().getSize (); }
|
|
bool isExhausted() { return getPosition () == getTotalLength (); }
|
|
int read (void* destBuffer, int maxBytesToRead)
|
|
{
|
|
size_t actualBytes = 0;
|
|
m_file.read (destBuffer, maxBytesToRead, &actualBytes);
|
|
return actualBytes;
|
|
}
|
|
|
|
int64 getPosition() { return m_file.getPosition (); }
|
|
bool setPosition (int64 newPosition) { return m_file.setPosition (newPosition); }
|
|
void skipNextBytes (int64 numBytesToSkip) { m_file.setPosition (getPosition () + numBytesToSkip); }
|
|
|
|
private:
|
|
RandomAccessFile& m_file;
|
|
};
|
|
|
|
class BEAST_API RandomAccessFileOutputStream : public OutputStream
|
|
{
|
|
public:
|
|
explicit RandomAccessFileOutputStream (RandomAccessFile& file) : m_file (file) { }
|
|
|
|
void flush() { m_file.flush (); }
|
|
int64 getPosition() { return m_file.getPosition (); }
|
|
bool setPosition (int64 newPosition) { return m_file.setPosition (newPosition); }
|
|
bool write (const void* dataToWrite, size_t numberOfBytes) { return m_file.write (dataToWrite, numberOfBytes); }
|
|
|
|
private:
|
|
RandomAccessFile& m_file;
|
|
};
|
|
|
|
#endif
|
|
|