Serenity Operating System
at master 189 lines 4.2 kB view raw
1/* 2 * Copyright (c) 2020, Sergey Bugaev <bugaevc@serenityos.org> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#pragma once 8 9#include <AK/Types.h> 10#include <Kernel/FileSystem/Plan9FS/Definitions.h> 11#include <Kernel/KBuffer.h> 12#include <Kernel/KBufferBuilder.h> 13 14namespace Kernel { 15 16class Plan9FS; 17class Plan9FSInode; 18 19class Plan9FSMessage { 20 friend class Plan9FS; 21 friend class Plan9FSInode; 22 23public: 24 enum class Type : u8 { 25 // 9P2000.L 26 Tlerror = 6, 27 Rlerror = 7, 28 Tstatfs = 8, 29 Rstatfs = 9, 30 31 Tlopen = 12, 32 Rlopen = 13, 33 Tlcreate = 14, 34 Rlcreate = 15, 35 Tsymlink = 16, 36 Rsymlink = 17, 37 Tmknod = 18, 38 Rmknod = 19, 39 Trename = 20, 40 Rrename = 21, 41 Treadlink = 22, 42 Rreadlink = 23, 43 Tgetattr = 24, 44 Rgetattr = 25, 45 Tsetattr = 26, 46 Rsetattr = 27, 47 48 Txattrwalk = 30, 49 Rxattrwalk = 31, 50 Txattrcreate = 32, 51 Rxattrcreate = 33, 52 53 Treaddir = 40, 54 Rreaddir = 41, 55 56 Tfsync = 50, 57 Rfsync = 51, 58 Tlock = 52, 59 Rlock = 53, 60 Tgetlock = 54, 61 Rgetlock = 55, 62 63 Tlink = 70, 64 Rlink = 71, 65 Tmkdir = 72, 66 Rmkdir = 73, 67 Trenameat = 74, 68 Rrenameat = 75, 69 Tunlinkat = 76, 70 Runlinkat = 77, 71 72 // 9P2000 73 Tversion = 100, 74 Rversion = 101, 75 Tauth = 102, 76 Rauth = 103, 77 Tattach = 104, 78 Rattach = 105, 79 Terror = 106, 80 Rerror = 107, 81 Tflush = 108, 82 Rflush = 109, 83 Twalk = 110, 84 Rwalk = 111, 85 Topen = 112, 86 Ropen = 113, 87 Tcreate = 114, 88 Rcreate = 115, 89 Tread = 116, 90 Rread = 117, 91 Twrite = 118, 92 Rwrite = 119, 93 Tclunk = 120, 94 Rclunk = 121, 95 Tremove = 122, 96 Rremove = 123, 97 Tstat = 124, 98 Rstat = 125, 99 Twstat = 126, 100 Rwstat = 127 101 }; 102 103 class Decoder { 104 public: 105 explicit Decoder(StringView data) 106 : m_data(data) 107 { 108 } 109 110 Decoder& operator>>(u8&); 111 Decoder& operator>>(u16&); 112 Decoder& operator>>(u32&); 113 Decoder& operator>>(u64&); 114 Decoder& operator>>(StringView&); 115 Decoder& operator>>(Plan9FSQIdentifier&); 116 StringView read_data(); 117 118 bool has_more_data() const { return !m_data.is_empty(); } 119 120 private: 121 StringView m_data; 122 123 template<typename N> 124 Decoder& read_number(N& number) 125 { 126 VERIFY(sizeof(number) <= m_data.length()); 127 memcpy(&number, m_data.characters_without_null_termination(), sizeof(number)); 128 m_data = m_data.substring_view(sizeof(number), m_data.length() - sizeof(number)); 129 return *this; 130 } 131 }; 132 133 Plan9FSMessage& operator<<(u8); 134 Plan9FSMessage& operator<<(u16); 135 Plan9FSMessage& operator<<(u32); 136 Plan9FSMessage& operator<<(u64); 137 Plan9FSMessage& operator<<(StringView); 138 ErrorOr<void> append_data(StringView); 139 140 template<typename T> 141 Plan9FSMessage& operator>>(T& t) 142 { 143 VERIFY(m_have_been_built); 144 m_built.decoder >> t; 145 return *this; 146 } 147 148 StringView read_data() 149 { 150 VERIFY(m_have_been_built); 151 return m_built.decoder.read_data(); 152 } 153 154 Type type() const { return m_type; } 155 u16 tag() const { return m_tag; } 156 157 Plan9FSMessage(Plan9FS&, Type); 158 Plan9FSMessage(NonnullOwnPtr<KBuffer>&&); 159 ~Plan9FSMessage(); 160 Plan9FSMessage& operator=(Plan9FSMessage&&); 161 162 KBuffer const& build(); 163 164 static constexpr size_t max_header_size = 24; 165 166private: 167 template<typename N> 168 Plan9FSMessage& append_number(N number) 169 { 170 VERIFY(!m_have_been_built); 171 // FIXME: Handle append failure. 172 (void)m_builder.append(reinterpret_cast<char const*>(&number), sizeof(number)); 173 return *this; 174 } 175 176 union { 177 KBufferBuilder m_builder; 178 struct { 179 NonnullOwnPtr<KBuffer> buffer; 180 Decoder decoder; 181 } m_built; 182 }; 183 184 u16 m_tag { 0 }; 185 Type m_type { 0 }; 186 bool m_have_been_built { false }; 187}; 188 189}