Merge pull request #70 from Henneberg-Systemdesign/support-for-get-partial-object
Support for get partial object
This commit is contained in:
commit
c9518f345f
|
@ -596,11 +596,19 @@ int SMTPFileSystem::open(const char *path, struct fuse_file_info *file_info)
|
|||
} else {
|
||||
tmp_path = m_tmp_files_pool.makeTmpPath(std_path);
|
||||
|
||||
int rval = m_device.filePull(std_path, tmp_path);
|
||||
if (rval != 0)
|
||||
return -rval;
|
||||
// only copy the file if needed
|
||||
if (!hasPartialObjectSupport()) {
|
||||
int rval = m_device.filePull(std_path, tmp_path);
|
||||
if (rval != 0)
|
||||
return -rval;
|
||||
} else {
|
||||
int fd = ::creat(tmp_path.c_str(), S_IRUSR | S_IWUSR);
|
||||
::close(fd);
|
||||
}
|
||||
}
|
||||
|
||||
// we create the tmp file even if we can use partial get/send to
|
||||
// have a valid file descriptor
|
||||
int fd = ::open(tmp_path.c_str(), file_info->flags);
|
||||
if (fd < 0) {
|
||||
::unlink(tmp_path.c_str());
|
||||
|
@ -620,24 +628,38 @@ int SMTPFileSystem::open(const char *path, struct fuse_file_info *file_info)
|
|||
int SMTPFileSystem::read(const char *path, char *buf, size_t size,
|
||||
off_t offset, struct fuse_file_info *file_info)
|
||||
{
|
||||
int rval = ::pread(file_info->fh, buf, size, offset);
|
||||
if (rval < 0)
|
||||
return -errno;
|
||||
int rval = 0;
|
||||
if (hasPartialObjectSupport()) {
|
||||
const std::string std_path(path);
|
||||
rval = m_device.fileRead(std_path, buf, size, offset);
|
||||
} else {
|
||||
rval = ::pread(file_info->fh, buf, size, offset);
|
||||
if (rval < 0)
|
||||
return -errno;
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
int SMTPFileSystem::write(const char *path, const char *buf, size_t size,
|
||||
off_t offset, struct fuse_file_info *file_info)
|
||||
{
|
||||
const TypeTmpFile *tmp_file = m_tmp_files_pool.getFile(std::string(path));
|
||||
if (!tmp_file)
|
||||
return -EINVAL;
|
||||
int rval = 0;
|
||||
if (hasPartialObjectSupport()) {
|
||||
const std::string std_path(path);
|
||||
rval = m_device.fileWrite(std_path, buf, size, offset);
|
||||
} else {
|
||||
const TypeTmpFile *tmp_file = m_tmp_files_pool.getFile(std::string(path));
|
||||
if (!tmp_file)
|
||||
return -EINVAL;
|
||||
|
||||
int rval = ::pwrite(file_info->fh, buf, size, offset);
|
||||
if (rval < 0)
|
||||
return -errno;
|
||||
rval = ::pwrite(file_info->fh, buf, size, offset);
|
||||
if (rval < 0)
|
||||
return -errno;
|
||||
|
||||
const_cast<TypeTmpFile*>(tmp_file)->setModified();
|
||||
}
|
||||
|
||||
const_cast<TypeTmpFile*>(tmp_file)->setModified();
|
||||
return rval;
|
||||
}
|
||||
|
||||
|
@ -764,3 +786,9 @@ int SMTPFileSystem::ftruncate(const char *path, off_t offset,
|
|||
const_cast<TypeTmpFile*>(tmp_file)->setModified();
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool SMTPFileSystem::hasPartialObjectSupport()
|
||||
{
|
||||
MTPDevice::Capabilities caps = m_device.getCapabilities();
|
||||
return (caps.canGetPartialObject() && caps.canSendPartialObject());
|
||||
}
|
||||
|
|
|
@ -104,10 +104,7 @@ public:
|
|||
int create(const char *path, mode_t mode, fuse_file_info *file_info);
|
||||
|
||||
private:
|
||||
static bool removeDir(const std::string &dirname);
|
||||
|
||||
bool createTmpDir();
|
||||
bool removeTmpDir();
|
||||
bool hasPartialObjectSupport();
|
||||
|
||||
static std::unique_ptr<SMTPFileSystem> s_instance;
|
||||
struct fuse_args m_args;
|
||||
|
|
|
@ -467,6 +467,64 @@ int MTPDevice::rename(const std::string &oldpath, const std::string &newpath)
|
|||
#endif
|
||||
}
|
||||
|
||||
int MTPDevice::fileRead(const std::string &path, char *buf, size_t size,
|
||||
off_t offset)
|
||||
{
|
||||
const std::string path_basename(smtpfs_basename(path));
|
||||
const std::string path_dirname(smtpfs_dirname(path));
|
||||
const TypeDir *dir_parent = dirFetchContent(path_dirname);
|
||||
const TypeFile *file_to_fetch = dir_parent ?
|
||||
dir_parent->file(path_basename) : nullptr;
|
||||
if (!dir_parent) {
|
||||
logerr("Can not fetch '", path, "'.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (!file_to_fetch) {
|
||||
logerr("No such file '", path, "'.\n");
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
// all systems clear
|
||||
unsigned char *tmp_buf;
|
||||
unsigned int tmp_size;
|
||||
int rval = LIBMTP_GetPartialObject(m_device, file_to_fetch->id(),
|
||||
offset, size, &tmp_buf, &tmp_size);
|
||||
if (tmp_size > 0) {
|
||||
memcpy(buf, tmp_buf, tmp_size);
|
||||
free(tmp_buf);
|
||||
}
|
||||
|
||||
if (rval != 0)
|
||||
return -EIO;
|
||||
return tmp_size;
|
||||
}
|
||||
|
||||
int MTPDevice::fileWrite(const std::string &path, const char *buf, size_t size,
|
||||
off_t offset)
|
||||
{
|
||||
const std::string path_basename(smtpfs_basename(path));
|
||||
const std::string path_dirname(smtpfs_dirname(path));
|
||||
const TypeDir *dir_parent = dirFetchContent(path_dirname);
|
||||
const TypeFile *file_to_fetch = dir_parent ?
|
||||
dir_parent->file(path_basename) : nullptr;
|
||||
if (!dir_parent) {
|
||||
logerr("Can not fetch '", path, "'.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (!file_to_fetch) {
|
||||
logerr("No such file '", path, "'.\n");
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
// all systems clear
|
||||
int rval = LIBMTP_SendPartialObject(m_device, file_to_fetch->id(),
|
||||
offset, (unsigned char *) buf, size);
|
||||
|
||||
if (rval < 0)
|
||||
return -EIO;
|
||||
return size;
|
||||
}
|
||||
|
||||
int MTPDevice::filePull(const std::string &src, const std::string &dst)
|
||||
{
|
||||
const std::string src_basename(smtpfs_basename(src));
|
||||
|
|
|
@ -78,6 +78,8 @@ public:
|
|||
|
||||
int rename(const std::string &oldpath, const std::string &newpath);
|
||||
|
||||
int fileRead(const std::string &path, char *buf, size_t size, off_t offset);
|
||||
int fileWrite(const std::string &path, const char *buf, size_t size, off_t offset);
|
||||
int filePull(const std::string &src, const std::string &dst);
|
||||
int filePush(const std::string &src, const std::string &dst);
|
||||
int fileRemove(const std::string &path);
|
||||
|
|
Loading…
Reference in New Issue