packet.h
1 // Copyright 2017 Citra Emulator Project 2 // Licensed under GPLv2 or any later version 3 // Refer to the license.txt file included. 4 5 #pragma once 6 7 #include <array> 8 #include <vector> 9 #include "common/common_types.h" 10 11 namespace Network { 12 13 /// A class that serializes data for network transfer. It also handles endianess 14 class Packet { 15 public: 16 Packet() = default; 17 ~Packet() = default; 18 19 /** 20 * Append data to the end of the packet 21 * @param data Pointer to the sequence of bytes to append 22 * @param size_in_bytes Number of bytes to append 23 */ 24 void Append(const void* data, std::size_t size_in_bytes); 25 26 /** 27 * Reads data from the current read position of the packet 28 * @param out_data Pointer where the data should get written to 29 * @param size_in_bytes Number of bytes to read 30 */ 31 void Read(void* out_data, std::size_t size_in_bytes); 32 33 /** 34 * Clear the packet 35 * After calling Clear, the packet is empty. 36 */ 37 void Clear(); 38 39 /** 40 * Ignores bytes while reading 41 * @param length THe number of bytes to ignore 42 */ 43 void IgnoreBytes(u32 length); 44 45 /** 46 * Get a pointer to the data contained in the packet 47 * @return Pointer to the data 48 */ 49 const void* GetData() const; 50 51 /** 52 * This function returns the number of bytes pointed to by 53 * what getData returns. 54 * @return Data size, in bytes 55 */ 56 std::size_t GetDataSize() const; 57 58 /** 59 * This function is useful to know if there is some data 60 * left to be read, without actually reading it. 61 * @return True if all data was read, false otherwise 62 */ 63 bool EndOfPacket() const; 64 65 explicit operator bool() const; 66 67 /// Overloads of operator >> to read data from the packet 68 Packet& operator>>(bool& out_data); 69 Packet& operator>>(s8& out_data); 70 Packet& operator>>(u8& out_data); 71 Packet& operator>>(s16& out_data); 72 Packet& operator>>(u16& out_data); 73 Packet& operator>>(s32& out_data); 74 Packet& operator>>(u32& out_data); 75 Packet& operator>>(s64& out_data); 76 Packet& operator>>(u64& out_data); 77 Packet& operator>>(float& out_data); 78 Packet& operator>>(double& out_data); 79 Packet& operator>>(char* out_data); 80 Packet& operator>>(std::string& out_data); 81 template <typename T> 82 Packet& operator>>(std::vector<T>& out_data); 83 template <typename T, std::size_t S> 84 Packet& operator>>(std::array<T, S>& out_data); 85 86 /// Overloads of operator << to write data into the packet 87 Packet& operator<<(bool in_data); 88 Packet& operator<<(s8 in_data); 89 Packet& operator<<(u8 in_data); 90 Packet& operator<<(s16 in_data); 91 Packet& operator<<(u16 in_data); 92 Packet& operator<<(s32 in_data); 93 Packet& operator<<(u32 in_data); 94 Packet& operator<<(s64 in_data); 95 Packet& operator<<(u64 in_data); 96 Packet& operator<<(float in_data); 97 Packet& operator<<(double in_data); 98 Packet& operator<<(const char* in_data); 99 Packet& operator<<(const std::string& in_data); 100 template <typename T> 101 Packet& operator<<(const std::vector<T>& in_data); 102 template <typename T, std::size_t S> 103 Packet& operator<<(const std::array<T, S>& data); 104 105 private: 106 /** 107 * Check if the packet can extract a given number of bytes 108 * This function updates accordingly the state of the packet. 109 * @param size Size to check 110 * @return True if size bytes can be read from the packet 111 */ 112 bool CheckSize(std::size_t size); 113 114 // Member data 115 std::vector<char> data; ///< Data stored in the packet 116 std::size_t read_pos = 0; ///< Current reading position in the packet 117 bool is_valid = true; ///< Reading state of the packet 118 }; 119 120 template <typename T> 121 Packet& Packet::operator>>(std::vector<T>& out_data) { 122 // First extract the size 123 u32 size = 0; 124 *this >> size; 125 out_data.resize(size); 126 127 // Then extract the data 128 for (std::size_t i = 0; i < out_data.size(); ++i) { 129 T character; 130 *this >> character; 131 out_data[i] = character; 132 } 133 return *this; 134 } 135 136 template <typename T, std::size_t S> 137 Packet& Packet::operator>>(std::array<T, S>& out_data) { 138 for (std::size_t i = 0; i < out_data.size(); ++i) { 139 T character; 140 *this >> character; 141 out_data[i] = character; 142 } 143 return *this; 144 } 145 146 template <typename T> 147 Packet& Packet::operator<<(const std::vector<T>& in_data) { 148 // First insert the size 149 *this << static_cast<u32>(in_data.size()); 150 151 // Then insert the data 152 for (std::size_t i = 0; i < in_data.size(); ++i) { 153 *this << in_data[i]; 154 } 155 return *this; 156 } 157 158 template <typename T, std::size_t S> 159 Packet& Packet::operator<<(const std::array<T, S>& in_data) { 160 for (std::size_t i = 0; i < in_data.size(); ++i) { 161 *this << in_data[i]; 162 } 163 return *this; 164 } 165 166 } // namespace Network