Serenity Operating System
1/*
2 * Copyright (c) 2020, Sergey Bugaev <bugaevc@serenityos.org>
3 *
4 * SPDX-License-Identifier: BSD-2-Clause
5 */
6
7#include <Kernel/FileSystem/Plan9FS/FileSystem.h>
8#include <Kernel/FileSystem/Plan9FS/Inode.h>
9#include <Kernel/FileSystem/Plan9FS/Message.h>
10
11namespace Kernel {
12
13Plan9FSMessage& Plan9FSMessage::operator<<(u8 number)
14{
15 return append_number(number);
16}
17
18Plan9FSMessage& Plan9FSMessage::operator<<(u16 number)
19{
20 return append_number(number);
21}
22
23Plan9FSMessage& Plan9FSMessage::operator<<(u32 number)
24{
25 return append_number(number);
26}
27
28Plan9FSMessage& Plan9FSMessage::operator<<(u64 number)
29{
30 return append_number(number);
31}
32
33Plan9FSMessage& Plan9FSMessage::operator<<(StringView string)
34{
35 *this << static_cast<u16>(string.length());
36 // FIXME: Handle append failure.
37 (void)m_builder.append(string);
38 return *this;
39}
40
41ErrorOr<void> Plan9FSMessage::append_data(StringView data)
42{
43 *this << static_cast<u32>(data.length());
44 TRY(m_builder.append(data));
45 return {};
46}
47
48Plan9FSMessage::Decoder& Plan9FSMessage::Decoder::operator>>(u8& number)
49{
50 return read_number(number);
51}
52
53Plan9FSMessage::Decoder& Plan9FSMessage::Decoder::operator>>(u16& number)
54{
55 return read_number(number);
56}
57
58Plan9FSMessage::Decoder& Plan9FSMessage::Decoder::operator>>(u32& number)
59{
60 return read_number(number);
61}
62
63Plan9FSMessage::Decoder& Plan9FSMessage::Decoder::operator>>(u64& number)
64{
65 return read_number(number);
66}
67
68Plan9FSMessage::Decoder& Plan9FSMessage::Decoder::operator>>(Plan9FSQIdentifier& qid)
69{
70 return *this >> qid.type >> qid.version >> qid.path;
71}
72
73Plan9FSMessage::Decoder& Plan9FSMessage::Decoder::operator>>(StringView& string)
74{
75 u16 length;
76 *this >> length;
77 VERIFY(length <= m_data.length());
78 string = m_data.substring_view(0, length);
79 m_data = m_data.substring_view_starting_after_substring(string);
80 return *this;
81}
82
83StringView Plan9FSMessage::Decoder::read_data()
84{
85 u32 length;
86 *this >> length;
87 VERIFY(length <= m_data.length());
88 auto data = m_data.substring_view(0, length);
89 m_data = m_data.substring_view_starting_after_substring(data);
90 return data;
91}
92
93Plan9FSMessage::Plan9FSMessage(Plan9FS& fs, Type type)
94 : m_builder(KBufferBuilder::try_create().release_value()) // FIXME: Don't assume KBufferBuilder allocation success.
95 , m_tag(fs.allocate_tag())
96 , m_type(type)
97 , m_have_been_built(false)
98{
99 u32 size_placeholder = 0;
100 *this << size_placeholder << (u8)type << m_tag;
101}
102
103Plan9FSMessage::Plan9FSMessage(NonnullOwnPtr<KBuffer>&& buffer)
104 : m_built { move(buffer), Decoder({ buffer->bytes() }) }
105 , m_have_been_built(true)
106{
107 u32 size;
108 u8 raw_type;
109 *this >> size >> raw_type >> m_tag;
110 m_type = (Type)raw_type;
111}
112
113Plan9FSMessage::~Plan9FSMessage()
114{
115 if (m_have_been_built) {
116 m_built.buffer.~NonnullOwnPtr<KBuffer>();
117 m_built.decoder.~Decoder();
118 } else {
119 m_builder.~KBufferBuilder();
120 }
121}
122
123Plan9FSMessage& Plan9FSMessage::operator=(Plan9FSMessage&& message)
124{
125 m_tag = message.m_tag;
126 m_type = message.m_type;
127
128 if (m_have_been_built) {
129 m_built.buffer.~NonnullOwnPtr<KBuffer>();
130 m_built.decoder.~Decoder();
131 } else {
132 m_builder.~KBufferBuilder();
133 }
134
135 m_have_been_built = message.m_have_been_built;
136 if (m_have_been_built) {
137 new (&m_built.buffer) NonnullOwnPtr<KBuffer>(move(message.m_built.buffer));
138 new (&m_built.decoder) Decoder(move(message.m_built.decoder));
139 } else {
140 new (&m_builder) KBufferBuilder(move(message.m_builder));
141 }
142
143 return *this;
144}
145
146KBuffer const& Plan9FSMessage::build()
147{
148 VERIFY(!m_have_been_built);
149
150 auto tmp_buffer = m_builder.build();
151
152 // FIXME: We should not assume success here.
153 VERIFY(tmp_buffer);
154
155 m_have_been_built = true;
156 m_builder.~KBufferBuilder();
157
158 new (&m_built.buffer) NonnullOwnPtr<KBuffer>(tmp_buffer.release_nonnull());
159 new (&m_built.decoder) Decoder({ m_built.buffer->data(), m_built.buffer->size() });
160 u32* size = reinterpret_cast<u32*>(m_built.buffer->data());
161 *size = m_built.buffer->size();
162 return *m_built.buffer;
163}
164
165}