diff options
Diffstat (limited to 'third_party/wasm2c/include/wabt/stream.h')
-rw-r--r-- | third_party/wasm2c/include/wabt/stream.h | 229 |
1 files changed, 229 insertions, 0 deletions
diff --git a/third_party/wasm2c/include/wabt/stream.h b/third_party/wasm2c/include/wabt/stream.h new file mode 100644 index 0000000000..67f50975eb --- /dev/null +++ b/third_party/wasm2c/include/wabt/stream.h @@ -0,0 +1,229 @@ +/* + * Copyright 2016 WebAssembly Community Group participants + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WABT_STREAM_H_ +#define WABT_STREAM_H_ + +#include <cassert> +#include <memory> +#include <vector> + +#include "wabt/common.h" + +namespace wabt { + +/* whether to display the ASCII characters in the debug output for + * write_memory */ +enum class PrintChars { + No = 0, + Yes = 1, +}; + +class Stream { + public: + explicit Stream(Stream* log_stream = nullptr); + virtual ~Stream() = default; + + size_t offset() { return offset_; } + Result result() { return result_; } + + void set_log_stream(Stream* stream) { + assert(stream); + log_stream_ = stream; + } + + Stream& log_stream() { + assert(log_stream_); + return *log_stream_; + } + + bool has_log_stream() const { return log_stream_ != nullptr; } + + void ClearOffset() { offset_ = 0; } + void AddOffset(ssize_t delta); + + void WriteData(const void* src, + size_t size, + const char* desc = nullptr, + PrintChars = PrintChars::No); + + template <typename T> + void WriteData(const std::vector<T> src, + const char* desc, + PrintChars print_chars = PrintChars::No) { + if (!src.empty()) { + WriteData(src.data(), src.size() * sizeof(T), desc, print_chars); + } + } + + void WriteDataAt(size_t offset, + const void* src, + size_t size, + const char* desc = nullptr, + PrintChars = PrintChars::No); + + void MoveData(size_t dst_offset, size_t src_offset, size_t size); + + void Truncate(size_t size); + + void WABT_PRINTF_FORMAT(2, 3) Writef(const char* format, ...); + + // Specified as uint32_t instead of uint8_t so we can check if the value + // given is in range before wrapping. + void WriteU8(uint32_t value, + const char* desc = nullptr, + PrintChars print_chars = PrintChars::No) { + assert(value <= UINT8_MAX); + Write(static_cast<uint8_t>(value), desc, print_chars); + } + void WriteU32(uint32_t value, + const char* desc = nullptr, + PrintChars print_chars = PrintChars::No) { + Write(value, desc, print_chars); + } + void WriteU64(uint64_t value, + const char* desc = nullptr, + PrintChars print_chars = PrintChars::No) { + Write(value, desc, print_chars); + } + void WriteU128(v128 value, + const char* desc = nullptr, + PrintChars print_chars = PrintChars::No) { + Write(value, desc, print_chars); + } + + void WriteChar(char c, + const char* desc = nullptr, + PrintChars print_chars = PrintChars::No) { + WriteU8(static_cast<unsigned char>(c), desc, print_chars); + } + + // Dump memory as text, similar to the xxd format. + void WriteMemoryDump(const void* start, + size_t size, + size_t offset = 0, + PrintChars print_chars = PrintChars::No, + const char* prefix = nullptr, + const char* desc = nullptr); + + // Convenience functions for writing enums. + template <typename T> + void WriteU8Enum(T value, + const char* desc = nullptr, + PrintChars print_chars = PrintChars::No) { + WriteU8(static_cast<uint32_t>(value), desc, print_chars); + } + + virtual void Flush() {} + + protected: + virtual Result WriteDataImpl(size_t offset, + const void* data, + size_t size) = 0; + virtual Result MoveDataImpl(size_t dst_offset, + size_t src_offset, + size_t size) = 0; + virtual Result TruncateImpl(size_t size) = 0; + + private: + template <typename T> + void Write(const T& data, const char* desc, PrintChars print_chars) { +#if WABT_BIG_ENDIAN + char tmp[sizeof(T)]; + memcpy(tmp, &data, sizeof(tmp)); + SwapBytesSized(tmp, sizeof(tmp)); + WriteData(tmp, sizeof(tmp), desc, print_chars); +#else + WriteData(&data, sizeof(data), desc, print_chars); +#endif + } + + size_t offset_; + Result result_; + // Not owned. If non-null, log all writes to this stream. + Stream* log_stream_; +}; + +struct OutputBuffer { + Result WriteToFile(std::string_view filename) const; + Result WriteToStdout() const; + + void clear() { data.clear(); } + size_t size() const { return data.size(); } + + std::vector<uint8_t> data; +}; + +class MemoryStream : public Stream { + public: + WABT_DISALLOW_COPY_AND_ASSIGN(MemoryStream); + MemoryStream(MemoryStream&&) = default; + explicit MemoryStream(Stream* log_stream = nullptr); + explicit MemoryStream(std::unique_ptr<OutputBuffer>&&, + Stream* log_stream = nullptr); + + OutputBuffer& output_buffer() { return *buf_; } + std::unique_ptr<OutputBuffer> ReleaseOutputBuffer(); + + void Clear(); + + Result WriteToFile(std::string_view filename) { + return buf_->WriteToFile(filename); + } + + protected: + Result WriteDataImpl(size_t offset, const void* data, size_t size) override; + Result MoveDataImpl(size_t dst_offset, + size_t src_offset, + size_t size) override; + Result TruncateImpl(size_t size) override; + + private: + std::unique_ptr<OutputBuffer> buf_; +}; + +class FileStream : public Stream { + public: + WABT_DISALLOW_COPY_AND_ASSIGN(FileStream); + explicit FileStream(std::string_view filename, Stream* log_stream = nullptr); + explicit FileStream(FILE*, Stream* log_stream = nullptr); + FileStream(FileStream&&); + FileStream& operator=(FileStream&&); + ~FileStream() override; + + static std::unique_ptr<FileStream> CreateStdout(); + static std::unique_ptr<FileStream> CreateStderr(); + + bool is_open() const { return file_ != nullptr; } + + void Flush() override; + + protected: + Result WriteDataImpl(size_t offset, const void* data, size_t size) override; + Result MoveDataImpl(size_t dst_offset, + size_t src_offset, + size_t size) override; + Result TruncateImpl(size_t size) override; + + private: + FILE* file_; + size_t offset_; + bool should_close_; +}; + +} // namespace wabt + +#endif /* WABT_STREAM_H_ */ |