LibNRG  0.0.1
Networking for Real-time Games library
 All Classes Files Functions Variables Friends
nrg_codec.h
Go to the documentation of this file.
1 /*
2  LibNRG - Networking for Real-time Games
3 
4  Copyright (C) 2012-2014 Alex Baines <alex@abaines.me.uk>
5 
6  This software is provided 'as-is', without any express or implied
7  warranty. In no event will the authors be held liable for any damages
8  arising from the use of this software.
9 
10  Permission is granted to anyone to use this software for any purpose,
11  including commercial applications, and to alter it and redistribute it
12  freely, subject to the following restrictions:
13 
14  1. The origin of this software must not be misrepresented; you must not
15  claim that you wrote the original software. If you use this software
16  in a product, an acknowledgment in the product documentation would be
17  appreciated but is not required.
18  2. Altered source versions must be plainly marked as such, and must not be
19  misrepresented as being the original software.
20  3. This notice may not be removed or altered from any source distribution.
21 */
25 #ifndef NRG_CODEC_H
26 #define NRG_CODEC_H
27 #include "nrg_core.h"
28 #include "nrg_varint.h"
29 #include <string>
30 #include <type_traits>
31 
32 namespace nrg {
33 
34 namespace detail {
35 
36 using namespace std;
37 
38 template<class T>
39 class has_encode_decode {
40  template<class C, C> struct S {};
41  template<class X> static true_type check(S<size_t (X::*)(Packet&) const, &X::encode>*,
42  S<size_t (X::*)(Packet&), &X::decode>*);
43  template<class X> static false_type check(...);
44 public:
45  static const bool value = decltype(check<T>(0, 0))::value;
46 };
47 
48 }
49 
50 using std::enable_if;
51 using detail::has_encode_decode;
52 
54 template<class T, class E = void>
55 struct Codec {
57  size_t encode(Packet& p, const T& data){
58  p.write(data);
59  return sizeof(data);
60  }
61 
63  size_t decode(Packet& p, T& data){
64  if(p.remaining() >= sizeof(data)){
65  p.read(data);
66  return sizeof(data);
67  } else {
68  return 0;
69  }
70  }
71 };
72 
74 template<class T>
75 struct Codec<T, typename enable_if<has_encode_decode<T>::value>::type> {
77  size_t encode(Packet& p, const T& data){
78  return data.encode(p);
79  }
80 
82  size_t decode(Packet& p, T& data){
83  return data.decode(p);
84  }
85 };
86 
88 template<size_t len>
89 struct Codec<char[len]> {
90 
92  size_t encode(Packet& p, const char (&data)[len]){
93  p.writeArray(data, len);
94  return len;
95  }
96 
98  size_t decode(Packet& p, char (&data)[len]){
99  if(p.remaining() >= len){
100  p.readArray(&data, len);
101  return len;
102  } else {
103  return 0;
104  }
105  }
106 };
107 
109 template<>
110 struct Codec<std::string> {
111 
113  size_t encode(Packet& p, const std::string& str){
114  size_t ret = UVarint(str.length()).encode(p);
115  p.writeArray(str.c_str(), str.length());
116  return ret + str.length();
117  }
118 
120  size_t decode(Packet& p, std::string& str){
121  if(!p.remaining()) return 0;
122 
123  UVarint v;
124  size_t read_bytes = 0;
125 
126  if((read_bytes = v.decode(p)) == 0) return 0;
127  if(p.remaining() < v.get()) return 0;
128 
129  str = std::string(reinterpret_cast<const char*>(p.getPointer()), v.get());
130 
131  p.seek(v.get(), SEEK_CUR);
132  return read_bytes + v.get();
133  }
134 };
135 
136 }
137 
138 #endif
Packet & seek(off_t offset, int whence)
Seeks the packet to some offset using SEEK_SET, SEEK_CUR or SEEK_END.
size_t decode(Packet &p, T &data)
Decodes bytes from p into data, returns the number of bytes read or 0 on error.
Definition: nrg_codec.h:63
Default undeclared template instance to cause a compilation error for non-integer types...
Definition: nrg_varint.h:83
size_t remaining() const
Get the amount of data that can be read from the internal pointer's current position.
Definition: nrg_packet.h:134
Class for storing data to be sent / received across the network.
Definition: nrg_packet.h:58
void read(T &v)
Generic read function with endian conversion, be careful with types like size_t that differ across pl...
Definition: nrg_packet.h:115
const uint8_t * getPointer() const
Returns the internal pointer.
Definition: nrg_packet.h:137
size_t decode(Packet &p, T &data)
Calls the decode method of data to decode itself from the Packet p.
Definition: nrg_codec.h:82
Encodes and Decodes any type into a Packet object.
Definition: nrg_codec.h:55
size_t encode(Packet &p, const T &data)
Calls the encode method of data to encode itself into the Packet p.
Definition: nrg_codec.h:77
PacketReadable & readArray(uint8_t *v, size_t size)
Read an array of size size into v, make sure it's big enough!
size_t decode(Packet &p, char(&data)[len])
Decodes bytes from p into data, returns the number of bytes read or 0 on error.
Definition: nrg_codec.h:98
size_t encode(Packet &p, const std::string &str)
Encodes data into p by prefixing the string with its length as a Varint.
Definition: nrg_codec.h:113
PacketWritable & writeArray(const void *v, size_t size)
Write an array of size size, no endian conversion is performed.
Common defines and includes used by all the other nrg header files.
size_t decode(Packet &p, std::string &str)
Decodes bytes from p into data, returns the number of bytes read or 0 on error.
Definition: nrg_codec.h:120
void write(const T &v)
Generic write function with endian conversion, be careful with types like size_t that differ across p...
Definition: nrg_packet.h:94
size_t encode(Packet &p, const T &data)
Encodes data into p, and retuns the number of bytes written.
Definition: nrg_codec.h:57
Template implementation of variable-length integers, following the same format as Google's Protobufs...
size_t encode(Packet &p, const char(&data)[len])
Encodes data into p, and retuns the number of bytes written.
Definition: nrg_codec.h:92