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