Artic Base: Fix fallback read/write not being chunked (#171)

This commit is contained in:
PabloMK7 2024-07-07 19:10:47 +02:00 committed by GitHub
parent 9b39b43e90
commit 1e2be72e5e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -387,24 +387,34 @@ ResultVal<std::size_t> ArticFileBackend::Read(u64 offset, std::size_t length, u8
return cache->Read(file_handle, offset, length, buffer); return cache->Read(file_handle, offset, length, buffer);
} }
size_t read_amount = 0;
while (read_amount != length) {
size_t to_read =
std::min<size_t>(client->GetServerRequestMaxSize() - 0x100, length - read_amount);
auto req = client->NewRequest("FSFILE_Read"); auto req = client->NewRequest("FSFILE_Read");
req.AddParameterS32(file_handle); req.AddParameterS32(file_handle);
req.AddParameterU64(offset); req.AddParameterS64(static_cast<s64>(offset + read_amount));
req.AddParameterU32(static_cast<u32>(length)); req.AddParameterS32(static_cast<s32>(to_read));
auto resp = client->Send(req); auto resp = client->Send(req);
auto res = ArticArchive::RespResult(resp); if (!resp.has_value() || !resp->Succeeded())
return Result(-1);
auto res = Result(static_cast<u32>(resp->GetMethodResult()));
if (res.IsError()) if (res.IsError())
return res; return res;
auto read_buf = resp->GetResponseBuffer(0); auto read_buff = resp->GetResponseBuffer(0);
if (!read_buf || read_buf->second > length) { if (!read_buff.has_value())
return std::size_t(0); return Result(-1);
} size_t actually_read = read_buff->second;
memcpy(buffer, read_buf->first, read_buf->second); memcpy(buffer + read_amount, read_buff->first, actually_read);
return read_buf->second; read_amount += actually_read;
if (actually_read != to_read)
break;
}
return read_amount;
} }
ResultVal<std::size_t> ArticFileBackend::Write(u64 offset, std::size_t length, bool flush, ResultVal<std::size_t> ArticFileBackend::Write(u64 offset, std::size_t length, bool flush,
@ -415,25 +425,36 @@ ResultVal<std::size_t> ArticFileBackend::Write(u64 offset, std::size_t length, b
if (cache != nullptr) { if (cache != nullptr) {
return cache->Write(file_handle, offset, length, buffer, flags); return cache->Write(file_handle, offset, length, buffer, flags);
} else { } else {
size_t written_amount = 0;
while (written_amount != length) {
size_t to_write = std::min<size_t>(client->GetServerRequestMaxSize() - 0x100,
length - written_amount);
auto req = client->NewRequest("FSFILE_Write"); auto req = client->NewRequest("FSFILE_Write");
req.AddParameterS32(file_handle); req.AddParameterS32(file_handle);
req.AddParameterU64(offset); req.AddParameterS64(static_cast<s64>(offset + written_amount));
req.AddParameterU32(static_cast<u32>(length)); req.AddParameterS32(static_cast<s32>(to_write));
req.AddParameterU32(flags); req.AddParameterS32(static_cast<s32>(flags));
req.AddParameterBuffer(buffer, length); req.AddParameterBuffer(buffer + written_amount, to_write);
auto resp = client->Send(req); auto resp = client->Send(req);
auto res = ArticArchive::RespResult(resp); if (!resp.has_value() || !resp->Succeeded())
return Result(-1);
auto res = Result(static_cast<u32>(resp->GetMethodResult()));
if (res.IsError()) if (res.IsError())
return res; return res;
auto writen_buf = resp->GetResponseS32(0); auto actually_written_opt = resp->GetResponseS32(0);
if (!writen_buf) { if (!actually_written_opt.has_value())
return std::size_t(0); return Result(-1);
}
return std::size_t(*writen_buf); size_t actually_written = static_cast<size_t>(actually_written_opt.value());
written_amount += actually_written;
if (actually_written != to_write)
break;
}
return written_amount;
} }
} }