SelectedFile.cpp 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. /*
  2. * Copyright (c) 2024, Tim Flynn <trflynn89@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <AK/LexicalPath.h>
  7. #include <LibCore/File.h>
  8. #include <LibIPC/Decoder.h>
  9. #include <LibIPC/Encoder.h>
  10. #include <LibWeb/HTML/SelectedFile.h>
  11. namespace Web::HTML {
  12. ErrorOr<SelectedFile> SelectedFile::from_file_path(ByteString const& file_path)
  13. {
  14. // https://html.spec.whatwg.org/multipage/input.html#file-upload-state-(type=file):concept-input-file-path
  15. // Filenames must not contain path components, even in the case that a user has selected an entire directory
  16. // hierarchy or multiple files with the same name from different directories.
  17. auto name = LexicalPath::basename(file_path);
  18. auto file = TRY(Core::File::open(file_path, Core::File::OpenMode::Read));
  19. return SelectedFile { move(name), IPC::File { *file } };
  20. }
  21. SelectedFile::SelectedFile(ByteString name, ByteBuffer contents)
  22. : m_name(move(name))
  23. , m_file_or_contents(move(contents))
  24. {
  25. }
  26. SelectedFile::SelectedFile(ByteString name, IPC::File file)
  27. : m_name(move(name))
  28. , m_file_or_contents(move(file))
  29. {
  30. }
  31. ByteBuffer SelectedFile::take_contents()
  32. {
  33. VERIFY(m_file_or_contents.has<ByteBuffer>());
  34. return move(m_file_or_contents.get<ByteBuffer>());
  35. }
  36. }
  37. template<>
  38. ErrorOr<void> IPC::encode(Encoder& encoder, Web::HTML::SelectedFile const& file)
  39. {
  40. TRY(encoder.encode(file.name()));
  41. TRY(encoder.encode(file.file_or_contents()));
  42. return {};
  43. }
  44. template<>
  45. ErrorOr<Web::HTML::SelectedFile> IPC::decode(Decoder& decoder)
  46. {
  47. auto name = TRY(decoder.decode<ByteString>());
  48. auto file_or_contents = TRY((decoder.decode<Variant<IPC::File, ByteBuffer>>()));
  49. ByteBuffer contents;
  50. if (file_or_contents.has<IPC::File>()) {
  51. auto file = TRY(Core::File::adopt_fd(file_or_contents.get<IPC::File>().take_fd(), Core::File::OpenMode::Read));
  52. contents = TRY(file->read_until_eof());
  53. } else {
  54. contents = move(file_or_contents.get<ByteBuffer>());
  55. }
  56. return Web::HTML::SelectedFile { move(name), move(contents) };
  57. }