// Copyright 2021 The Fuchsia Authors // Copyright (c) 2008 Travis Geiselbrecht // // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file or at // https://opensource.org/licenses/MIT #ifndef ZIRCON_KERNEL_LIB_LIBC_INCLUDE_STRING_FILE_H_ #define ZIRCON_KERNEL_LIB_LIBC_INCLUDE_STRING_FILE_H_ #ifdef __cplusplus #include #include #include #include // FILE* wrapper over a string. class StringFile : public FILE { public: StringFile() = delete; StringFile(const StringFile &) = delete; StringFile operator=(const StringFile &) = delete; explicit StringFile(ktl::span s) : FILE(this), buffer_(s) {} ~StringFile() = default; // Adds a null character at the end of the current buffer and returns a view // into the written section. ktl::span take() &&; // Returns |str.size()| and writes as much of |str| as it would fit in the // buffer [offest_, size - 1) while reserving the last byte for null // character. int Write(ktl::string_view str); // Returns a region representing the currently used portion of the buffer. ktl::span used_region() const { return (offset_ > 0) ? ktl::span{buffer_.data(), offset_} : ktl::span{}; } // Returns a region representing the remaining unused space in the buffer, // _not_ including the space reserved for the final null character. ktl::span available_region() const { const size_t available = ktl::max(buffer_.size() - offset_, 1) - 1; return (available > 0) ? ktl::span{buffer_.data() + offset_, available} : ktl::span{}; } // Skip up to |amt| bytes in the buffer, advancing the write pointer as if we // had written data, but without actually changing the buffer. void Skip(size_t amt) { amt = ktl::min(amt, available_region().size()); offset_ += amt; } // Provide two ways for users to convert the currently used buffer into a // string_view. Given a string file |S|, users may say either: // // 1) S.as_string_view(); // or // 2) static_cast(S); // // to perform the conversion. // ktl::string_view as_string_view() const { return (offset_ > 0) ? ktl::string_view{buffer_.data(), offset_} : ktl::string_view{}; } explicit operator ktl::string_view() const { return this->as_string_view(); } private: ktl::span buffer_; size_t offset_ = 0; }; #endif // __cplusplus #endif // ZIRCON_KERNEL_LIB_LIBC_INCLUDE_STRING_FILE_H_