summaryrefslogtreecommitdiff
path: root/src/writer.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/writer.cc')
-rw-r--r--src/writer.cc209
1 files changed, 84 insertions, 125 deletions
diff --git a/src/writer.cc b/src/writer.cc
index 8e24abc0..a408ff32 100644
--- a/src/writer.cc
+++ b/src/writer.cc
@@ -22,177 +22,136 @@
#include <stdio.h>
#include <stdlib.h>
+#include <utility>
+
#define ERROR0(msg) fprintf(stderr, "%s:%d: " msg, __FILE__, __LINE__)
#define ERROR(fmt, ...) \
fprintf(stderr, "%s:%d: " fmt, __FILE__, __LINE__, __VA_ARGS__)
-#define INITIAL_OUTPUT_BUFFER_CAPACITY (64 * 1024)
-
namespace wabt {
-static Result write_data_to_file(size_t offset,
- const void* data,
- size_t size,
- void* user_data) {
- if (size == 0)
- return Result::Ok;
- FileWriter* writer = static_cast<FileWriter*>(user_data);
- if (offset != writer->offset) {
- if (fseek(writer->file, offset, SEEK_SET) != 0) {
- ERROR("fseek offset=%" PRIzd " failed, errno=%d\n", size, errno);
- return Result::Error;
- }
- writer->offset = offset;
- }
- if (fwrite(data, size, 1, writer->file) != 1) {
- ERROR("fwrite size=%" PRIzd " failed, errno=%d\n", size, errno);
+Result OutputBuffer::WriteToFile(const char* filename) const {
+ FILE* file = fopen(filename, "wb");
+ if (!file) {
+ ERROR("unable to open %s for writing\n", filename);
return Result::Error;
}
- writer->offset += size;
- return Result::Ok;
-}
-static Result move_data_in_file(size_t dst_offset,
- size_t src_offset,
- size_t size,
- void* user_data) {
- if (size == 0)
+ if (data.empty()) {
return Result::Ok;
- /* TODO(binji): implement if needed. */
- ERROR0("move_data_in_file not implemented!\n");
- return Result::Error;
-}
-
-void init_file_writer_existing(FileWriter* writer, FILE* file) {
- WABT_ZERO_MEMORY(*writer);
- writer->file = file;
- writer->offset = 0;
- writer->base.user_data = writer;
- writer->base.write_data = write_data_to_file;
- writer->base.move_data = move_data_in_file;
-}
+ }
-Result init_file_writer(FileWriter* writer, const char* filename) {
- FILE* file = fopen(filename, "wb");
- if (!file) {
- ERROR("fopen name=\"%s\" failed, errno=%d\n", filename, errno);
+ 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);
return Result::Error;
}
- init_file_writer_existing(writer, file);
+ fclose(file);
return Result::Ok;
}
-void close_file_writer(FileWriter* writer) {
- fclose(writer->file);
-}
+MemoryWriter::MemoryWriter() : buf_(new OutputBuffer()) {}
-void init_output_buffer(OutputBuffer* buf, size_t initial_capacity) {
- assert(initial_capacity != 0);
- buf->start = new char[initial_capacity]();
- buf->size = 0;
- buf->capacity = initial_capacity;
-}
+MemoryWriter::MemoryWriter(std::unique_ptr<OutputBuffer> buf)
+ : buf_(std::move(buf)) {}
-static void ensure_output_buffer_capacity(OutputBuffer* buf,
- size_t ensure_capacity) {
- if (ensure_capacity > buf->capacity) {
- assert(buf->capacity != 0);
- size_t new_capacity = buf->capacity * 2;
- while (new_capacity < ensure_capacity)
- new_capacity *= 2;
- char* new_data = new char [new_capacity];
- memcpy(new_data, buf->start, buf->capacity);
- memset(new_data + buf->capacity, 0, new_capacity - buf->capacity);
- delete [] buf->start;
- buf->start = new_data;
- buf->capacity = new_capacity;
- }
+std::unique_ptr<OutputBuffer> MemoryWriter::ReleaseOutputBuffer() {
+ return std::move(buf_);
}
-static Result write_data_to_output_buffer(size_t offset,
- const void* data,
- size_t size,
- void* user_data) {
- MemoryWriter* writer = static_cast<MemoryWriter*>(user_data);
- size_t end = offset + size;
- ensure_output_buffer_capacity(&writer->buf, end);
- memcpy(writer->buf.start + offset, data, size);
- if (end > writer->buf.size)
- writer->buf.size = end;
+Result MemoryWriter::WriteData(size_t dst_offset,
+ const void* src,
+ size_t size) {
+ 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;
}
-static Result move_data_in_output_buffer(size_t dst_offset,
- size_t src_offset,
- size_t size,
- void* user_data) {
- MemoryWriter* writer = static_cast<MemoryWriter*>(user_data);
+Result MemoryWriter::MoveData(size_t dst_offset,
+ size_t src_offset,
+ size_t size) {
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;
- ensure_output_buffer_capacity(&writer->buf, end);
- void* dst = reinterpret_cast<void*>(
- reinterpret_cast<size_t>(writer->buf.start) + dst_offset);
- void* src = reinterpret_cast<void*>(
- reinterpret_cast<size_t>(writer->buf.start) + src_offset);
+ 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);
- if (end > writer->buf.size)
- writer->buf.size = end;
return Result::Ok;
}
-Result init_mem_writer(MemoryWriter* writer) {
- WABT_ZERO_MEMORY(*writer);
- writer->base.user_data = writer;
- writer->base.write_data = write_data_to_output_buffer;
- writer->base.move_data = move_data_in_output_buffer;
- init_output_buffer(&writer->buf, INITIAL_OUTPUT_BUFFER_CAPACITY);
- return Result::Ok;
+FileWriter::FileWriter(FILE* file)
+ : file_(file), offset_(0), should_close_(false) {}
+
+FileWriter::FileWriter(const char* filename)
+ : file_(nullptr), offset_(0), should_close_(false) {
+ file_ = fopen(filename, "wb");
+
+ // 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, errno);
+ }
}
-Result init_mem_writer_existing(MemoryWriter* writer, OutputBuffer* buf) {
- WABT_ZERO_MEMORY(*writer);
- writer->base.user_data = writer;
- writer->base.write_data = write_data_to_output_buffer;
- writer->base.move_data = move_data_in_output_buffer;
- writer->buf = *buf;
- /* Clear buffer, since ownership has passed to the writer. */
- WABT_ZERO_MEMORY(*buf);
- return Result::Ok;
+FileWriter::FileWriter(FileWriter&& other) {
+ *this = std::move(other);
}
-void steal_mem_writer_output_buffer(MemoryWriter* writer,
- OutputBuffer* out_buf) {
- *out_buf = writer->buf;
- writer->buf.start = nullptr;
- writer->buf.size = 0;
- writer->buf.capacity = 0;
+FileWriter& FileWriter::operator=(FileWriter&& other) {
+ file_ = other.file_;
+ offset_ = other.offset_;
+ should_close_ = other.should_close_;
+ other.file_ = nullptr;
+ other.offset_ = 0;
+ other.should_close_ = false;
+ return *this;
}
-void close_mem_writer(MemoryWriter* writer) {
- destroy_output_buffer(&writer->buf);
+FileWriter::~FileWriter() {
+ // We don't want to close existing files (stdout/sterr, for example).
+ if (should_close_) {
+ fclose(file_);
+ }
}
-Result write_output_buffer_to_file(OutputBuffer* buf, const char* filename) {
- FILE* file = fopen(filename, "wb");
- if (!file) {
- ERROR("unable to open %s for writing\n", filename);
+Result FileWriter::WriteData(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;
}
-
- ssize_t bytes = fwrite(buf->start, 1, buf->size, file);
- if (bytes < 0 || static_cast<size_t>(bytes) != buf->size) {
- ERROR("failed to write %" PRIzd " bytes to %s\n", buf->size, filename);
+ if (fwrite(data, size, 1, file_) != 1) {
+ ERROR("fwrite size=%" PRIzd " failed, errno=%d\n", size, errno);
return Result::Error;
}
-
- fclose(file);
+ offset_ += size;
return Result::Ok;
}
-void destroy_output_buffer(OutputBuffer* buf) {
- delete[] buf->start;
+Result FileWriter::MoveData(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;
}
} // namespace wabt