mirror of
https://github.com/moses-smt/mosesdecoder.git
synced 2024-11-11 05:52:56 +03:00
79 lines
2.5 KiB
C++
79 lines
2.5 KiB
C++
#include "util/stream/io.hh"
|
|
|
|
#include "util/file.hh"
|
|
#include "util/stream/chain.hh"
|
|
|
|
#include <cstddef>
|
|
|
|
namespace util {
|
|
namespace stream {
|
|
|
|
ReadSizeException::ReadSizeException() throw() {}
|
|
ReadSizeException::~ReadSizeException() throw() {}
|
|
|
|
void Read::Run(const ChainPosition &position) {
|
|
const std::size_t block_size = position.GetChain().BlockSize();
|
|
const std::size_t entry_size = position.GetChain().EntrySize();
|
|
for (Link link(position); link; ++link) {
|
|
std::size_t got = util::ReadOrEOF(file_, link->Get(), block_size);
|
|
UTIL_THROW_IF(got % entry_size, ReadSizeException, "File ended with " << got << " bytes, not a multiple of " << entry_size << ".");
|
|
if (got == 0) {
|
|
link.Poison();
|
|
return;
|
|
} else {
|
|
link->SetValidSize(got);
|
|
}
|
|
}
|
|
}
|
|
|
|
void PRead::Run(const ChainPosition &position) {
|
|
scoped_fd owner;
|
|
if (own_) owner.reset(file_);
|
|
const uint64_t size = SizeOrThrow(file_);
|
|
UTIL_THROW_IF(size % static_cast<uint64_t>(position.GetChain().EntrySize()), ReadSizeException, "File size " << file_ << " size is " << size << " not a multiple of " << position.GetChain().EntrySize());
|
|
const std::size_t block_size = position.GetChain().BlockSize();
|
|
const uint64_t block_size64 = static_cast<uint64_t>(block_size);
|
|
Link link(position);
|
|
uint64_t offset = 0;
|
|
for (; offset + block_size64 < size; offset += block_size64, ++link) {
|
|
ErsatzPRead(file_, link->Get(), block_size, offset);
|
|
link->SetValidSize(block_size);
|
|
}
|
|
// size - offset is <= block_size, so it casts to 32-bit fine.
|
|
if (size - offset) {
|
|
ErsatzPRead(file_, link->Get(), size - offset, offset);
|
|
link->SetValidSize(size - offset);
|
|
++link;
|
|
}
|
|
link.Poison();
|
|
}
|
|
|
|
void Write::Run(const ChainPosition &position) {
|
|
for (Link link(position); link; ++link) {
|
|
WriteOrThrow(file_, link->Get(), link->ValidSize());
|
|
}
|
|
}
|
|
|
|
void WriteAndRecycle::Run(const ChainPosition &position) {
|
|
const std::size_t block_size = position.GetChain().BlockSize();
|
|
for (Link link(position); link; ++link) {
|
|
WriteOrThrow(file_, link->Get(), link->ValidSize());
|
|
link->SetValidSize(block_size);
|
|
}
|
|
}
|
|
|
|
void PWriteAndRecycle::Run(const ChainPosition &position) {
|
|
const std::size_t block_size = position.GetChain().BlockSize();
|
|
uint64_t offset = 0;
|
|
for (Link link(position); link; ++link) {
|
|
ErsatzPWrite(file_, link->Get(), link->ValidSize(), offset);
|
|
offset += link->ValidSize();
|
|
link->SetValidSize(block_size);
|
|
}
|
|
// Trim file to size.
|
|
util::ResizeOrThrow(file_, offset);
|
|
}
|
|
|
|
} // namespace stream
|
|
} // namespace util
|