/* * 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 #include #include "common.h" #include "writer.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: Stream(Writer* writer, Stream* log_stream = nullptr); 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 AddOffset(ssize_t delta); void WriteData(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 WriteDataAt(size_t offset, const void* src, size_t size, const char* desc = nullptr, PrintChars = PrintChars::No); 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(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 WriteChar(char c, const char* desc = nullptr, PrintChars print_chars = PrintChars::No) { WriteU8(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, const char* prefix = nullptr, const char* desc = nullptr, PrintChars print_chars = PrintChars::No); // Convenience functions for writing enums. template void WriteU8Enum(T value, const char* desc = nullptr, PrintChars print_chars = PrintChars::No) { WriteU8(static_cast(value), desc, print_chars); } private: template void Write(const T& data, const char* desc, PrintChars print_chars) { WriteData(&data, sizeof(data), desc, print_chars); } Writer* writer_; // Not owned. size_t offset_; Result result_; // Not owned. If non-null, log all writes to this stream. Stream* log_stream_; }; class MemoryStream : public Stream { public: MemoryStream(); MemoryWriter& writer() { return writer_; } std::unique_ptr ReleaseOutputBuffer() { return writer_.ReleaseOutputBuffer(); } Result WriteToFile(const char* filename) { return writer_.output_buffer().WriteToFile(filename); } private: MemoryWriter writer_; }; class FileStream : public Stream { public: explicit FileStream(const char* filename); explicit FileStream(FILE*); FileWriter& writer() { return writer_; } static std::unique_ptr CreateStdout(); static std::unique_ptr CreateStderr(); bool is_open() const { return writer_.is_open(); } private: FileWriter writer_; }; } // namespace wabt #endif /* WABT_STREAM_H_ */