| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263 |
- // Copyright 2017 Citra Emulator Project
- // Licensed under GPLv2 or any later version
- // Refer to the license.txt file included.
- #ifdef _WIN32
- #include <winsock2.h>
- #else
- #include <arpa/inet.h>
- #endif
- #include <cstring>
- #include <string>
- #include "network/packet.h"
- namespace Network {
- #ifndef htonll
- u64 htonll(u64 x) {
- return ((1 == htonl(1)) ? (x) : ((uint64_t)htonl((x)&0xFFFFFFFF) << 32) | htonl((x) >> 32));
- }
- #endif
- #ifndef ntohll
- u64 ntohll(u64 x) {
- return ((1 == ntohl(1)) ? (x) : ((uint64_t)ntohl((x)&0xFFFFFFFF) << 32) | ntohl((x) >> 32));
- }
- #endif
- void Packet::Append(const void* in_data, std::size_t size_in_bytes) {
- if (in_data && (size_in_bytes > 0)) {
- std::size_t start = data.size();
- data.resize(start + size_in_bytes);
- std::memcpy(&data[start], in_data, size_in_bytes);
- }
- }
- void Packet::Read(void* out_data, std::size_t size_in_bytes) {
- if (out_data && CheckSize(size_in_bytes)) {
- std::memcpy(out_data, &data[read_pos], size_in_bytes);
- read_pos += size_in_bytes;
- }
- }
- void Packet::Clear() {
- data.clear();
- read_pos = 0;
- is_valid = true;
- }
- const void* Packet::GetData() const {
- return !data.empty() ? &data[0] : nullptr;
- }
- void Packet::IgnoreBytes(u32 length) {
- read_pos += length;
- }
- std::size_t Packet::GetDataSize() const {
- return data.size();
- }
- bool Packet::EndOfPacket() const {
- return read_pos >= data.size();
- }
- Packet::operator bool() const {
- return is_valid ? &Packet::CheckSize : nullptr;
- }
- Packet& Packet::operator>>(bool& out_data) {
- u8 value;
- if (*this >> value) {
- out_data = (value != 0);
- }
- return *this;
- }
- Packet& Packet::operator>>(s8& out_data) {
- Read(&out_data, sizeof(out_data));
- return *this;
- }
- Packet& Packet::operator>>(u8& out_data) {
- Read(&out_data, sizeof(out_data));
- return *this;
- }
- Packet& Packet::operator>>(s16& out_data) {
- s16 value;
- Read(&value, sizeof(value));
- out_data = ntohs(value);
- return *this;
- }
- Packet& Packet::operator>>(u16& out_data) {
- u16 value;
- Read(&value, sizeof(value));
- out_data = ntohs(value);
- return *this;
- }
- Packet& Packet::operator>>(s32& out_data) {
- s32 value;
- Read(&value, sizeof(value));
- out_data = ntohl(value);
- return *this;
- }
- Packet& Packet::operator>>(u32& out_data) {
- u32 value;
- Read(&value, sizeof(value));
- out_data = ntohl(value);
- return *this;
- }
- Packet& Packet::operator>>(s64& out_data) {
- s64 value;
- Read(&value, sizeof(value));
- out_data = ntohll(value);
- return *this;
- }
- Packet& Packet::operator>>(u64& out_data) {
- u64 value;
- Read(&value, sizeof(value));
- out_data = ntohll(value);
- return *this;
- }
- Packet& Packet::operator>>(float& out_data) {
- Read(&out_data, sizeof(out_data));
- return *this;
- }
- Packet& Packet::operator>>(double& out_data) {
- Read(&out_data, sizeof(out_data));
- return *this;
- }
- Packet& Packet::operator>>(char* out_data) {
- // First extract string length
- u32 length = 0;
- *this >> length;
- if ((length > 0) && CheckSize(length)) {
- // Then extract characters
- std::memcpy(out_data, &data[read_pos], length);
- out_data[length] = '\0';
- // Update reading position
- read_pos += length;
- }
- return *this;
- }
- Packet& Packet::operator>>(std::string& out_data) {
- // First extract string length
- u32 length = 0;
- *this >> length;
- out_data.clear();
- if ((length > 0) && CheckSize(length)) {
- // Then extract characters
- out_data.assign(&data[read_pos], length);
- // Update reading position
- read_pos += length;
- }
- return *this;
- }
- Packet& Packet::operator<<(bool in_data) {
- *this << static_cast<u8>(in_data);
- return *this;
- }
- Packet& Packet::operator<<(s8 in_data) {
- Append(&in_data, sizeof(in_data));
- return *this;
- }
- Packet& Packet::operator<<(u8 in_data) {
- Append(&in_data, sizeof(in_data));
- return *this;
- }
- Packet& Packet::operator<<(s16 in_data) {
- s16 toWrite = htons(in_data);
- Append(&toWrite, sizeof(toWrite));
- return *this;
- }
- Packet& Packet::operator<<(u16 in_data) {
- u16 toWrite = htons(in_data);
- Append(&toWrite, sizeof(toWrite));
- return *this;
- }
- Packet& Packet::operator<<(s32 in_data) {
- s32 toWrite = htonl(in_data);
- Append(&toWrite, sizeof(toWrite));
- return *this;
- }
- Packet& Packet::operator<<(u32 in_data) {
- u32 toWrite = htonl(in_data);
- Append(&toWrite, sizeof(toWrite));
- return *this;
- }
- Packet& Packet::operator<<(s64 in_data) {
- s64 toWrite = htonll(in_data);
- Append(&toWrite, sizeof(toWrite));
- return *this;
- }
- Packet& Packet::operator<<(u64 in_data) {
- u64 toWrite = htonll(in_data);
- Append(&toWrite, sizeof(toWrite));
- return *this;
- }
- Packet& Packet::operator<<(float in_data) {
- Append(&in_data, sizeof(in_data));
- return *this;
- }
- Packet& Packet::operator<<(double in_data) {
- Append(&in_data, sizeof(in_data));
- return *this;
- }
- Packet& Packet::operator<<(const char* in_data) {
- // First insert string length
- u32 length = static_cast<u32>(std::strlen(in_data));
- *this << length;
- // Then insert characters
- Append(in_data, length * sizeof(char));
- return *this;
- }
- Packet& Packet::operator<<(const std::string& in_data) {
- // First insert string length
- u32 length = static_cast<u32>(in_data.size());
- *this << length;
- // Then insert characters
- if (length > 0)
- Append(in_data.c_str(), length * sizeof(std::string::value_type));
- return *this;
- }
- bool Packet::CheckSize(std::size_t size) {
- is_valid = is_valid && (read_pos + size <= data.size());
- return is_valid;
- }
- } // namespace Network
|