diff --git a/src/ox/fs/filestore.hpp b/src/ox/fs/filestore.hpp index 6044d52c8..166f1f354 100644 --- a/src/ox/fs/filestore.hpp +++ b/src/ox/fs/filestore.hpp @@ -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
::Inode::setData(void *data, typename Header::FsSize_t siz template -void *FileStore
::Inode::getData() { - return this + 1; +uint8_t *FileStore
::Inode::getData() { + return (uint8_t*) (this + 1); } @@ -538,14 +566,29 @@ void FileStore
::updateInodeAddress(InodeId_t id, typename Header::FsSize template int FileStore
::read(InodeId_t id, void *data, typename Header::FsSize_t *size) { auto inode = getInode(ptr(m_header.getRootInode()), id); + return inode ? read(inode, 0, inode->getDataLen(), data, size) : 1; +} + +template +int FileStore
::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(m_header.getRootInode()), id); + return inode ? read(inode, readStart, readSize, data, size) : 1; +} + +template +int FileStore
::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; } diff --git a/src/ox/fs/filesystem.hpp b/src/ox/fs/filesystem.hpp index f952bd1e3..bb06d0234 100644 --- a/src/ox/fs/filesystem.hpp +++ b/src/ox/fs/filesystem.hpp @@ -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::stat(uint64_t inode) { #pragma warning(disable:4244) #endif template -int FileSystemTemplate::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::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 +int FileSystemTemplate::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 diff --git a/src/ox/fs/oxfstool.cpp b/src/ox/fs/oxfstool.cpp index 1ce738242..9cf601f77 100644 --- a/src/ox/fs/oxfstool.cpp +++ b/src/ox/fs/oxfstool.cpp @@ -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);