summaryrefslogtreecommitdiff
path: root/lib/libc/include/string-file.h
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libc/include/string-file.h')
-rw-r--r--lib/libc/include/string-file.h79
1 files changed, 79 insertions, 0 deletions
diff --git a/lib/libc/include/string-file.h b/lib/libc/include/string-file.h
new file mode 100644
index 0000000..1632933
--- /dev/null
+++ b/lib/libc/include/string-file.h
@@ -0,0 +1,79 @@
+// 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 <stdio.h>
+
+#include <ktl/algorithm.h>
+#include <ktl/span.h>
+#include <ktl/string_view.h>
+
+// 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<char> 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<char> 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<char> used_region() const {
+ return (offset_ > 0) ? ktl::span<char>{buffer_.data(), offset_} : ktl::span<char>{};
+ }
+
+ // Returns a region representing the remaining unused space in the buffer,
+ // _not_ including the space reserved for the final null character.
+ ktl::span<char> available_region() const {
+ const size_t available = ktl::max<size_t>(buffer_.size() - offset_, 1) - 1;
+ return (available > 0) ? ktl::span<char>{buffer_.data() + offset_, available}
+ : ktl::span<char>{};
+ }
+
+ // 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<ktl::string_view>(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<char> buffer_;
+ size_t offset_ = 0;
+};
+
+#endif // __cplusplus
+
+#endif // ZIRCON_KERNEL_LIB_LIBC_INCLUDE_STRING_FILE_H_