Add a bounded read option for the file system
This commit is contained in:
+53
-10
@@ -103,7 +103,7 @@ class FileStore {
|
||||
|
||||
struct StatInfo {
|
||||
InodeId_t inodeId;
|
||||
typename Header::FsSize_t size;
|
||||
typename Header::FsSize_t size;
|
||||
uint8_t fileType;
|
||||
};
|
||||
|
||||
@@ -143,7 +143,7 @@ class FileStore {
|
||||
typename Header::FsSize_t getRight();
|
||||
|
||||
void setData(void *data, typename Header::FsSize_t size);
|
||||
void *getData();
|
||||
uint8_t *getData();
|
||||
};
|
||||
|
||||
Header m_header;
|
||||
@@ -186,6 +186,20 @@ class FileStore {
|
||||
*/
|
||||
int read(InodeId_t id, void *data, typename Header::FsSize_t *size);
|
||||
|
||||
/**
|
||||
* Reads the "file" at the given id. You are responsible for freeing
|
||||
* the data when done with it.
|
||||
* @param id id of the "file"
|
||||
* @param readStart where in the data to start reading
|
||||
* @param readSize how much data to read
|
||||
* @param data pointer to the pointer where the data is stored
|
||||
* @param size pointer to a value that will be assigned the size of data
|
||||
* @return 0 if read is a success
|
||||
*/
|
||||
int read(InodeId_t id, typename Header::FsSize_t readStart,
|
||||
typename Header::FsSize_t readSize, void *data,
|
||||
typename Header::FsSize_t *size);
|
||||
|
||||
/**
|
||||
* Reads the stat information of the inode of the given inode id.
|
||||
* If the returned inode id is 0, then the requested inode was not found.
|
||||
@@ -240,6 +254,20 @@ class FileStore {
|
||||
*/
|
||||
Inode *getInodeParent(Inode *root, InodeId_t id, typename Header::FsSize_t targetAddr);
|
||||
|
||||
/**
|
||||
* Reads the "file" at the given id. You are responsible for freeing
|
||||
* the data when done with it.
|
||||
* @param inode inode of the "file"
|
||||
* @param readStart where in the data to start reading
|
||||
* @param readSize how much data to read
|
||||
* @param data pointer to the pointer where the data is stored
|
||||
* @param size pointer to a value that will be assigned the size of data
|
||||
* @return 0 if read is a success
|
||||
*/
|
||||
int read(Inode *inode, typename Header::FsSize_t readStart,
|
||||
typename Header::FsSize_t readSize, void *data,
|
||||
typename Header::FsSize_t *size);
|
||||
|
||||
/**
|
||||
* Removes the inode of the given ID.
|
||||
* @param id the id of the file
|
||||
@@ -391,8 +419,8 @@ void FileStore<Header>::Inode::setData(void *data, typename Header::FsSize_t siz
|
||||
|
||||
|
||||
template<typename Header>
|
||||
void *FileStore<Header>::Inode::getData() {
|
||||
return this + 1;
|
||||
uint8_t *FileStore<Header>::Inode::getData() {
|
||||
return (uint8_t*) (this + 1);
|
||||
}
|
||||
|
||||
|
||||
@@ -538,14 +566,29 @@ void FileStore<Header>::updateInodeAddress(InodeId_t id, typename Header::FsSize
|
||||
template<typename Header>
|
||||
int FileStore<Header>::read(InodeId_t id, void *data, typename Header::FsSize_t *size) {
|
||||
auto inode = getInode(ptr<Inode*>(m_header.getRootInode()), id);
|
||||
return inode ? read(inode, 0, inode->getDataLen(), data, size) : 1;
|
||||
}
|
||||
|
||||
template<typename Header>
|
||||
int FileStore<Header>::read(InodeId_t id, typename Header::FsSize_t readStart,
|
||||
typename Header::FsSize_t readSize, void *data, typename Header::FsSize_t *size) {
|
||||
auto inode = getInode(ptr<Inode*>(m_header.getRootInode()), id);
|
||||
return inode ? read(inode, readStart, readSize, data, size) : 1;
|
||||
}
|
||||
|
||||
template<typename Header>
|
||||
int FileStore<Header>::read(Inode *inode, typename Header::FsSize_t readStart,
|
||||
typename Header::FsSize_t readSize, void *data, typename Header::FsSize_t *size) {
|
||||
int retval = 1;
|
||||
if (inode) {
|
||||
if (size) {
|
||||
*size = inode->getDataLen();
|
||||
}
|
||||
ox_memcpy(data, inode->getData(), inode->getDataLen());
|
||||
retval = 0;
|
||||
// be sure read size is not greater than what is available to read
|
||||
if (inode->getDataLen() + readStart < readSize) {
|
||||
readSize = inode->getDataLen();
|
||||
}
|
||||
if (size) {
|
||||
*size = readSize;
|
||||
}
|
||||
ox_memcpy(data, inode->getData() + readStart, inode->getDataLen());
|
||||
retval = 0;
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
@@ -34,7 +34,9 @@ class FileSystem {
|
||||
public:
|
||||
virtual ~FileSystem() {};
|
||||
|
||||
virtual int read(uint64_t inode, void *buffer, size_t size) = 0;
|
||||
virtual int read(uint64_t inode, void *buffer, size_t *size) = 0;
|
||||
|
||||
virtual int read(uint64_t inode, size_t readStart, size_t readSize, void *buffer, size_t *size) = 0;
|
||||
|
||||
virtual uint8_t *read(uint64_t inode, size_t *size) = 0;
|
||||
|
||||
@@ -110,9 +112,11 @@ class FileSystemTemplate: public FileSystem {
|
||||
|
||||
int read(const char *path, void *buffer);
|
||||
|
||||
uint8_t *read(uint64_t inode, size_t *size) override;
|
||||
int read(uint64_t inode, void *buffer, size_t *size) override;
|
||||
|
||||
int read(uint64_t inode, void *buffer, size_t size) override;
|
||||
int read(uint64_t inode, size_t readStart, size_t readSize, void *buffer, size_t *size);
|
||||
|
||||
uint8_t *read(uint64_t inode, size_t *size) override;
|
||||
|
||||
void resize(uint64_t size = 0) override;
|
||||
|
||||
@@ -174,18 +178,35 @@ FileStat FileSystemTemplate<FileStore, FS_TYPE>::stat(uint64_t inode) {
|
||||
#pragma warning(disable:4244)
|
||||
#endif
|
||||
template<typename FileStore, FsType FS_TYPE>
|
||||
int FileSystemTemplate<FileStore, FS_TYPE>::read(uint64_t inode, void *buffer, size_t size) {
|
||||
auto err = 1;
|
||||
auto s = store->stat(inode);
|
||||
if (size == s.size) {
|
||||
err = store->read(inode, buffer, nullptr);
|
||||
int FileSystemTemplate<FileStore, FS_TYPE>::read(uint64_t inode, void *buffer, size_t *size) {
|
||||
if (size) {
|
||||
auto stat = store->stat(inode);
|
||||
*size = stat.size;
|
||||
}
|
||||
return err;
|
||||
return store->read(inode, buffer, nullptr);
|
||||
;
|
||||
}
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(default:4244)
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4244)
|
||||
#endif
|
||||
template<typename FileStore, FsType FS_TYPE>
|
||||
int FileSystemTemplate<FileStore, FS_TYPE>::read(uint64_t inode, size_t readStart,
|
||||
size_t readSize, void *buffer,
|
||||
size_t *size) {
|
||||
if (size) {
|
||||
auto stat = store->stat(inode);
|
||||
*size = stat.size;
|
||||
}
|
||||
return store->read(inode, readStart, readSize, buffer, nullptr);
|
||||
}
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4244)
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4244)
|
||||
#endif
|
||||
|
||||
@@ -201,6 +201,7 @@ int write(int argc, char **args, bool expand) {
|
||||
auto needed = fs->size() + fs->spaceNeeded(srcSize);
|
||||
fsSize = needed;
|
||||
fs = expandCopyCleanup(fs, needed);
|
||||
fsBuff = fs->buff();
|
||||
}
|
||||
err |= fs->write(inode, srcBuff, srcSize);
|
||||
|
||||
@@ -231,7 +232,7 @@ int write(int argc, char **args, bool expand) {
|
||||
err = 1;
|
||||
}
|
||||
}
|
||||
delete []fsBuff;
|
||||
delete []srcBuff;
|
||||
} else {
|
||||
err = 1;
|
||||
fprintf(stderr, "Could not load source file: %s.\n", srcPath);
|
||||
|
||||
Reference in New Issue
Block a user