summaryrefslogtreecommitdiff
path: root/src/stream.cc
diff options
context:
space:
mode:
authorBen Smith <binjimin@gmail.com>2017-09-06 23:28:42 -0700
committerGitHub <noreply@github.com>2017-09-06 23:28:42 -0700
commit44853bc8996496fec161bd6ec48a0a41adf891ce (patch)
tree7772970640df751376c318d97bb71bac1945ebb6 /src/stream.cc
parent4a37785fd5a6fe8c65a814e77289194616a2696a (diff)
downloadwabt-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.cc152
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));