FileStream.h 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. /*
  2. * Copyright (c) 2020, the SerenityOS developers.
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #pragma once
  7. #include <AK/Buffered.h>
  8. #include <AK/ByteBuffer.h>
  9. #include <AK/Stream.h>
  10. #include <LibCore/File.h>
  11. namespace Core {
  12. class InputFileStream final : public InputStream {
  13. public:
  14. explicit InputFileStream(NonnullRefPtr<File> file)
  15. : m_file(file)
  16. {
  17. }
  18. static Result<InputFileStream, String> open(StringView filename, OpenMode mode = OpenMode::ReadOnly, mode_t permissions = 0644)
  19. {
  20. VERIFY(has_flag(mode, OpenMode::ReadOnly));
  21. auto file_result = File::open(filename, mode, permissions);
  22. if (file_result.is_error())
  23. return file_result.error();
  24. return InputFileStream { file_result.value() };
  25. }
  26. static Result<Buffered<InputFileStream>, String> open_buffered(StringView filename, OpenMode mode = OpenMode::ReadOnly, mode_t permissions = 0644)
  27. {
  28. VERIFY(has_flag(mode, OpenMode::ReadOnly));
  29. auto file_result = File::open(filename, mode, permissions);
  30. if (file_result.is_error())
  31. return file_result.error();
  32. return Buffered<InputFileStream> { file_result.value() };
  33. }
  34. size_t read(Bytes bytes) override
  35. {
  36. if (has_any_error())
  37. return 0;
  38. const auto buffer = m_file->read(bytes.size());
  39. return buffer.bytes().copy_to(bytes);
  40. }
  41. bool read_or_error(Bytes bytes) override
  42. {
  43. if (read(bytes) < bytes.size()) {
  44. set_fatal_error();
  45. return false;
  46. }
  47. return true;
  48. }
  49. bool discard_or_error(size_t count) override { return m_file->seek(count, SeekMode::FromCurrentPosition); }
  50. bool unreliable_eof() const override { return m_file->eof(); }
  51. void close()
  52. {
  53. if (!m_file->close())
  54. set_fatal_error();
  55. }
  56. private:
  57. NonnullRefPtr<File> m_file;
  58. };
  59. class OutputFileStream : public OutputStream {
  60. public:
  61. explicit OutputFileStream(NonnullRefPtr<File> file)
  62. : m_file(file)
  63. {
  64. }
  65. static Result<OutputFileStream, String> open(StringView filename, OpenMode mode = OpenMode::WriteOnly, mode_t permissions = 0644)
  66. {
  67. VERIFY(has_flag(mode, OpenMode::WriteOnly));
  68. auto file_result = File::open(filename, mode, permissions);
  69. if (file_result.is_error())
  70. return file_result.error();
  71. return OutputFileStream { file_result.value() };
  72. }
  73. static Result<Buffered<OutputFileStream>, String> open_buffered(StringView filename, OpenMode mode = OpenMode::WriteOnly, mode_t permissions = 0644)
  74. {
  75. VERIFY(has_flag(mode, OpenMode::WriteOnly));
  76. auto file_result = File::open(filename, mode, permissions);
  77. if (file_result.is_error())
  78. return file_result.error();
  79. return Buffered<OutputFileStream> { file_result.value() };
  80. }
  81. static OutputFileStream standard_output()
  82. {
  83. return OutputFileStream { Core::File::standard_output() };
  84. }
  85. static OutputFileStream standard_error()
  86. {
  87. return OutputFileStream { Core::File::standard_error() };
  88. }
  89. static Buffered<OutputFileStream> stdout_buffered()
  90. {
  91. return Buffered<OutputFileStream> { Core::File::standard_output() };
  92. }
  93. size_t write(ReadonlyBytes bytes) override
  94. {
  95. if (!m_file->write(bytes.data(), bytes.size())) {
  96. set_fatal_error();
  97. return 0;
  98. }
  99. return bytes.size();
  100. }
  101. bool write_or_error(ReadonlyBytes bytes) override
  102. {
  103. if (write(bytes) < bytes.size()) {
  104. set_fatal_error();
  105. return false;
  106. }
  107. return true;
  108. }
  109. void close()
  110. {
  111. if (!m_file->close())
  112. set_fatal_error();
  113. }
  114. private:
  115. NonnullRefPtr<File> m_file;
  116. };
  117. }