/ src / network / packet.h
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