1 #ifndef _NDB_BENCH_SERIALIZER_H_
2 #define _NDB_BENCH_SERIALIZER_H_
8 typedef uint8_t *(*generic_write_fn)(uint8_t *, const uint8_t *);
9 typedef const uint8_t *(*generic_read_fn)(const uint8_t *, uint8_t *);
10 typedef const uint8_t *(*generic_failsafe_read_fn)(const uint8_t *, size_t, uint8_t *);
11 typedef size_t (*generic_nbytes_fn)(const uint8_t *);
12 typedef size_t (*generic_skip_fn)(const uint8_t *, uint8_t *);
13 typedef size_t (*generic_failsafe_skip_fn)(const uint8_t *, size_t, uint8_t *);
15 // wraps a real serializer, exposing generic functions
16 template <typename Serializer>
17 struct generic_serializer {
18 typedef typename Serializer::obj_type obj_type;
20 static inline uint8_t *
21 write(uint8_t *buf, const uint8_t *obj)
23 return Serializer::write(buf, *reinterpret_cast<const obj_type *>(obj));
26 static inline const uint8_t *
27 read(const uint8_t *buf, uint8_t *obj)
29 return Serializer::read(buf, reinterpret_cast<obj_type *>(obj));
32 // returns nullptr on failure
33 static inline const uint8_t *
34 failsafe_read(const uint8_t *buf, size_t nbytes, uint8_t *obj)
36 return Serializer::failsafe_read(
37 buf, nbytes, reinterpret_cast<obj_type *>(obj));
41 nbytes(const uint8_t *obj)
43 return Serializer::nbytes(reinterpret_cast<const obj_type *>(obj));
47 skip(const uint8_t *stream, uint8_t *rawv)
49 return Serializer::skip(stream, rawv);
52 // returns 0 on failure
54 failsafe_skip(const uint8_t *stream, size_t nbytes, uint8_t *rawv)
56 return Serializer::failsafe_skip(stream, nbytes, rawv);
59 static inline constexpr size_t
62 return Serializer::max_bytes();
66 template <typename T, bool Compress>
70 static inline uint8_t *
71 write(uint8_t *buf, const T &obj)
75 return (uint8_t *) (p + 1);
78 static inline const uint8_t *
79 read(const uint8_t *buf, T *obj)
81 const T *p = (const T *) buf;
83 return (const uint8_t *) (p + 1);
86 static inline const uint8_t *
87 failsafe_read(const uint8_t *buf, size_t nbytes, T *obj)
89 if (unlikely(nbytes < sizeof(T)))
91 return read(buf, obj);
101 skip(const uint8_t *stream, uint8_t *rawv)
104 NDB_MEMCPY(rawv, stream, sizeof(T));
109 failsafe_skip(const uint8_t *stream, size_t nbytes, uint8_t *rawv)
111 if (unlikely(nbytes < sizeof(T)))
114 NDB_MEMCPY(rawv, stream, sizeof(T));
118 static inline constexpr size_t
125 // serializer<T, True> specializations
127 struct serializer<uint32_t, true> {
128 typedef uint32_t obj_type;
130 static inline uint8_t *
131 write(uint8_t *buf, uint32_t obj)
133 return write_uvint32(buf, obj);
136 static inline const uint8_t *
137 read(const uint8_t *buf, uint32_t *obj)
139 return read_uvint32(buf, obj);
142 static inline const uint8_t *
143 failsafe_read(const uint8_t *buf, size_t nbytes, uint32_t *obj)
145 return failsafe_read_uvint32(buf, nbytes, obj);
149 nbytes(const uint32_t *obj)
151 return size_uvint32(*obj);
155 skip(const uint8_t *stream, uint8_t *rawv)
157 return skip_uvint32(stream, rawv);
161 failsafe_skip(const uint8_t *stream, size_t nbytes, uint8_t *rawv)
163 return failsafe_skip_uvint32(stream, nbytes, rawv);
166 static inline constexpr size_t
174 struct serializer<int32_t, true> {
175 typedef int32_t obj_type;
177 static inline uint8_t *
178 write(uint8_t *buf, int32_t obj)
180 const uint32_t v = encode(obj);
181 return serializer<uint32_t, true>::write(buf, v);
184 static inline const uint8_t *
185 read(const uint8_t *buf, int32_t *obj)
188 buf = serializer<uint32_t, true>::read(buf, &v);
193 static inline const uint8_t *
194 failsafe_read(const uint8_t *buf, size_t nbytes, int32_t *obj)
197 buf = serializer<uint32_t, true>::failsafe_read(buf, nbytes, &v);
205 nbytes(const int32_t *obj)
207 const uint32_t v = encode(*obj);
208 return serializer<uint32_t, true>::nbytes(&v);
212 skip(const uint8_t *stream, uint8_t *rawv)
214 return skip_uvint32(stream, rawv);
218 failsafe_skip(const uint8_t *stream, size_t nbytes, uint8_t *rawv)
220 return failsafe_skip_uvint32(stream, nbytes, rawv);
223 static inline constexpr size_t
230 // zig-zag encoding from:
231 // http://code.google.com/p/protobuf/source/browse/trunk/src/google/protobuf/wire_format_lite.h
233 static inline ALWAYS_INLINE constexpr uint32_t
234 encode(int32_t value)
236 return (value << 1) ^ (value >> 31);
239 static inline ALWAYS_INLINE constexpr int32_t
240 decode(uint32_t value)
242 return (value >> 1) ^ -static_cast<int32_t>(value & 1);
246 #endif /* _NDB_BENCH_SERIALIZER_H_ */