#include "webfuse/ws/messagereader.hpp" #include "webfuse/filesystem/status.hpp" #include "webfuse/filesystem/filemode.hpp" #include "webfuse/filesystem/accessmode.hpp" #include "webfuse/filesystem/openflags.hpp" #include namespace webfuse { messagereader::messagereader(std::string & value) : data(std::move(value)) , pos(0) { } messagereader::messagereader(messagereader && other) { this->data = std::move(other.data); this->pos = other.pos; } messagereader& messagereader::operator=(messagereader && other) { if (this != &other) { this->data = std::move(other.data); this->pos = other.pos; } return *this; } int messagereader::read_result() { status value(read_i32()); return value.to_fusestatus(); } int messagereader::read_access_mode() { auto const value = read_u8(); access_mode mode(static_cast(value)); return mode.to_int(); } void messagereader::read_attr(struct stat * attr) { attr->st_ino = static_cast(read_u64()); attr->st_nlink = static_cast(read_u64()); attr->st_mode = read_mode(); attr->st_uid = static_cast(read_u32()); attr->st_gid = static_cast(read_u32()); attr->st_rdev = static_cast(read_u64()); attr->st_size = static_cast(read_u64()); attr->st_blocks = static_cast(read_u64()); attr->st_atim.tv_sec = static_cast(read_u64()); attr->st_atim.tv_nsec = static_cast(read_u32()); attr->st_mtim.tv_sec = static_cast(read_u64()); attr->st_mtim.tv_nsec = static_cast(read_u32()); attr->st_ctim.tv_sec = static_cast(read_u64()); attr->st_ctim.tv_nsec = static_cast(read_u32()); } void messagereader::read_statistics(struct statvfs * statistics) { statistics->f_bsize = read_u64(); statistics->f_frsize = read_u64(); statistics->f_blocks = read_u64(); statistics->f_bfree = read_u64(); statistics->f_bavail = read_u64(); statistics->f_files = read_u64(); statistics->f_ffree = read_u64(); statistics->f_namemax = read_u64(); } mode_t messagereader::read_mode() { filemode mode(read_u32()); return mode.to_mode(); } bool messagereader::read_bool() { return (1 == read_u8()); } uint8_t messagereader::read_u8() { if (pos < data.size()) { uint8_t value = static_cast(data[pos]); pos++; return value; } throw std::runtime_error("out of bounds"); } uint32_t messagereader::read_u32() { // NOLINTBEGIN(readability-magic-numbers) if ((pos + 3) < data.size()) { uint32_t value = ((static_cast(data[pos ]) & 0xff) << 24) | ((static_cast(data[pos + 1]) & 0xff) << 16) | ((static_cast(data[pos + 2]) & 0xff) << 8) | ((static_cast(data[pos + 3]) & 0xff) ); pos += 4; return value; } // NOLINTEND(readability-magic-numbers) throw std::runtime_error("out of bounds"); } uint64_t messagereader::read_u64() { // NOLINTBEGIN(readability-magic-numbers) if ((pos + 7) < data.size()) { uint32_t value = (static_cast(data[pos ] & 0xff) << 56) | (static_cast(data[pos + 1] & 0xff) << 48) | (static_cast(data[pos + 2] & 0xff) << 40) | (static_cast(data[pos + 3] & 0xff) << 32) | (static_cast(data[pos + 4] & 0xff) << 24) | (static_cast(data[pos + 5] & 0xff) << 16) | (static_cast(data[pos + 6] & 0xff) << 8) | (static_cast(data[pos + 7] & 0xff) ); pos += 8; return value; } // NOLINTEND(readability-magic-numbers) throw std::runtime_error("out of bounds"); } int32_t messagereader::read_i32() { uint32_t value = read_u32(); return static_cast(value); } std::string messagereader::read_str() { return std::move(read_bytes()); } std::string messagereader::read_bytes() { uint32_t size = read_u32(); if ((pos + size) <= data.size()) { std::string const value(&data[pos], size); pos += size; return std::move(value); } throw std::runtime_error("out of bounds"); } void messagereader::read_strings(std::vector &entries) { uint32_t const count = read_u32(); for(uint32_t i = 0; i < count; i++) { std::string entry = read_str(); entries.push_back(entry); } } void messagereader::read_time(struct timespec &time) { time.tv_sec = static_cast(read_u64()); time.tv_nsec = static_cast(read_u32()); } int messagereader::read_openflags() { auto const value = read_i32(); openflags flags(value); return flags.to_int(); } }