diff options
author | Ben Smith <binjimin@gmail.com> | 2017-09-06 23:28:42 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-09-06 23:28:42 -0700 |
commit | 44853bc8996496fec161bd6ec48a0a41adf891ce (patch) | |
tree | 7772970640df751376c318d97bb71bac1945ebb6 /src/stream.cc | |
parent | 4a37785fd5a6fe8c65a814e77289194616a2696a (diff) | |
download | wabt-44853bc8996496fec161bd6ec48a0a41adf891ce.tar.gz wabt-44853bc8996496fec161bd6ec48a0a41adf891ce.tar.bz2 wabt-44853bc8996496fec161bd6ec48a0a41adf891ce.zip |
Remove Writer class, move functionality into Stream (#613)
* Remove Writer class, move functionality into Stream
* Fix emscripten build
Diffstat (limited to 'src/stream.cc')
-rw-r--r-- | src/stream.cc | 152 |
1 files changed, 138 insertions, 14 deletions
diff --git a/src/stream.cc b/src/stream.cc index e976e82a..90d4e913 100644 --- a/src/stream.cc +++ b/src/stream.cc @@ -18,17 +18,19 @@ #include <cassert> #include <cctype> +#include <cerrno> #define DUMP_OCTETS_PER_LINE 16 #define DUMP_OCTETS_PER_GROUP 2 +#define ERROR0(msg) fprintf(stderr, "%s:%d: " msg, __FILE__, __LINE__) +#define ERROR(fmt, ...) \ + fprintf(stderr, "%s:%d: " fmt, __FILE__, __LINE__, __VA_ARGS__) + namespace wabt { -Stream::Stream(Writer* writer, Stream* log_stream) - : writer_(writer), - offset_(0), - result_(Result::Ok), - log_stream_(log_stream) {} +Stream::Stream(Stream* log_stream) + : offset_(0), result_(Result::Ok), log_stream_(log_stream) {} void Stream::AddOffset(ssize_t delta) { offset_ += delta; @@ -44,7 +46,7 @@ void Stream::WriteDataAt(size_t at, if (log_stream_) { log_stream_->WriteMemoryDump(src, size, at, print_chars, nullptr, desc); } - result_ = writer_->WriteData(at, src, size); + result_ = WriteDataImpl(at, src, size); } void Stream::WriteData(const void* src, @@ -63,7 +65,7 @@ void Stream::MoveData(size_t dst_offset, size_t src_offset, size_t size) { "; move data: [%" PRIzx ", %" PRIzx ") -> [%" PRIzx ", %" PRIzx ")\n", src_offset, src_offset + size, dst_offset, dst_offset + size); } - result_ = writer_->MoveData(dst_offset, src_offset, size); + result_ = MoveDataImpl(dst_offset, src_offset, size); } void Stream::Writef(const char* format, ...) { @@ -112,21 +114,143 @@ void Stream::WriteMemoryDump(const void* start, } } -MemoryStream::MemoryStream() : Stream(&writer_) {} +Result OutputBuffer::WriteToFile(string_view filename) const { + std::string filename_str = filename.to_string(); + FILE* file = fopen(filename_str.c_str(), "wb"); + if (!file) { + ERROR("unable to open %s for writing\n", filename_str.c_str()); + return Result::Error; + } + + if (data.empty()) { + fclose(file); + return Result::Ok; + } + + ssize_t bytes = fwrite(data.data(), 1, data.size(), file); + if (bytes < 0 || static_cast<size_t>(bytes) != data.size()) { + ERROR("failed to write %" PRIzd " bytes to %s\n", data.size(), + filename_str.c_str()); + fclose(file); + return Result::Error; + } + + fclose(file); + return Result::Ok; +} + +MemoryStream::MemoryStream(Stream* log_stream) + : Stream(log_stream), buf_(new OutputBuffer()) {} + +MemoryStream::MemoryStream(std::unique_ptr<OutputBuffer>&& buf, + Stream* log_stream) + : Stream(log_stream), buf_(std::move(buf)) {} + +std::unique_ptr<OutputBuffer> MemoryStream::ReleaseOutputBuffer() { + return std::move(buf_); +} + +Result MemoryStream::WriteDataImpl(size_t dst_offset, + const void* src, + size_t size) { + if (size == 0) + return Result::Ok; + size_t end = dst_offset + size; + if (end > buf_->data.size()) { + buf_->data.resize(end); + } + uint8_t* dst = &buf_->data[dst_offset]; + memcpy(dst, src, size); + return Result::Ok; +} + +Result MemoryStream::MoveDataImpl(size_t dst_offset, + size_t src_offset, + size_t size) { + if (size == 0) + return Result::Ok; + size_t src_end = src_offset + size; + size_t dst_end = dst_offset + size; + size_t end = src_end > dst_end ? src_end : dst_end; + if (end > buf_->data.size()) { + buf_->data.resize(end); + } + + uint8_t* dst = &buf_->data[dst_offset]; + uint8_t* src = &buf_->data[src_offset]; + memmove(dst, src, size); + return Result::Ok; +} + +FileStream::FileStream(string_view filename, Stream* log_stream) + : Stream(log_stream), file_(nullptr), offset_(0), should_close_(false) { + std::string filename_str = filename.to_string(); + file_ = fopen(filename_str.c_str(), "wb"); -FileStream::FileStream(string_view filename) - : Stream(&writer_), writer_(filename) {} + // TODO(binji): this is pretty cheesy, should come up with a better API. + if (file_) { + should_close_ = true; + } else { + ERROR("fopen name=\"%s\" failed, errno=%d\n", filename_str.c_str(), errno); + } +} -FileStream::FileStream(FILE* file) : Stream(&writer_), writer_(file) {} +FileStream::FileStream(FILE* file, Stream* log_stream) + : Stream(log_stream), file_(file), offset_(0), should_close_(false) {} -FileStream::FileStream(FileStream&& other) - : Stream(&writer_), writer_(std::move(other.writer_)) {} +FileStream::FileStream(FileStream&& other) { + *this = std::move(other); +} FileStream& FileStream::operator=(FileStream&& other) { - writer_ = std::move(other.writer_); + file_ = other.file_; + offset_ = other.offset_; + should_close_ = other.should_close_; + other.file_ = nullptr; + other.offset_ = 0; + other.should_close_ = false; return *this; } +FileStream::~FileStream() { + // We don't want to close existing files (stdout/sterr, for example). + if (should_close_) { + fclose(file_); + } +} + +Result FileStream::WriteDataImpl(size_t at, const void* data, size_t size) { + if (!file_) + return Result::Error; + if (size == 0) + return Result::Ok; + if (at != offset_) { + if (fseek(file_, at, SEEK_SET) != 0) { + ERROR("fseek offset=%" PRIzd " failed, errno=%d\n", size, errno); + return Result::Error; + } + offset_ = at; + } + if (fwrite(data, size, 1, file_) != 1) { + ERROR("fwrite size=%" PRIzd " failed, errno=%d\n", size, errno); + return Result::Error; + } + offset_ += size; + return Result::Ok; +} + +Result FileStream::MoveDataImpl(size_t dst_offset, + size_t src_offset, + size_t size) { + if (!file_) + return Result::Error; + if (size == 0) + return Result::Ok; + // TODO(binji): implement if needed. + ERROR0("FileWriter::MoveData not implemented!\n"); + return Result::Error; +} + // static std::unique_ptr<FileStream> FileStream::CreateStdout() { return std::unique_ptr<FileStream>(new FileStream(stdout)); |