Last active
August 29, 2015 14:08
-
-
Save codebrainz/765ec3b211f93455da3f to your computer and use it in GitHub Desktop.
Byte encoder for some basic types
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <cstdint> | |
#include <type_traits> | |
/* | |
* Encodes the value as bytes and inserts into the iterator. | |
* | |
* Example: | |
* std::vector<uint8_t> buf; | |
* int some_val = 0x12345678; | |
* encode(some_val, back_inserter(buf)); | |
* | |
* © 2014 Matthew Brush | |
*/ | |
template< typename ValueType, | |
typename ByteIterator, | |
typename SizeType = size_t, | |
typename std::enable_if< | |
std::is_integral<ValueType>::value | |
>::type* = nullptr > | |
void encode(ValueType value, ByteIterator iter) { | |
const SizeType bits_size(sizeof(ValueType) * 8); | |
unsigned long long as_int = static_cast<unsigned long long>(value); | |
for (SizeType shift=(bits_size - 8); shift != 0; shift-=8) { | |
*iter = static_cast<uint8_t>((as_int >> shift) & 0xFF); | |
++iter; | |
} | |
*iter = static_cast<uint8_t>(as_int & 0xFF); | |
} | |
template< typename ByteIterator, | |
typename SizeType = size_t > | |
void encode(float value, ByteIterator iter) { | |
union { float as_dbl; uint32_t as_int; } u = { value }; | |
encode<uint32_t, ByteIterator, SizeType>(u.as_int, iter); | |
} | |
template< typename ByteIterator, | |
typename SizeType = size_t > | |
void encode(double value, ByteIterator iter) { | |
union { double as_dbl; uint64_t as_int; } u = { value }; | |
encode<uint64_t, ByteIterator, SizeType>(u.as_int, iter); | |
} | |
#ifdef __GNUC__ | |
template< typename ByteIterator, | |
typename SizeType = size_t > | |
void encode(long double value, ByteIterator iter) { | |
const SizeType bits_size(sizeof(long double) * 8); | |
union { long double as_dbl; unsigned __int128 as_int; } u = { value }; | |
for (SizeType shift=(bits_size - 8); shift != 0; shift-=8) { | |
*iter = static_cast<uint8_t>((u.as_int >> shift) & 0xFF); | |
++iter; | |
} | |
*iter = static_cast<uint8_t>(u.as_int & 0xFF); | |
} | |
#endif | |
template< typename ByteIterator, | |
typename CharType = char, | |
typename SizeType = size_t > | |
void encode(const std::basic_string<CharType>& value, ByteIterator iter) { | |
encode<uint32_t, ByteIterator, SizeType>(value.size(), iter); | |
for (CharType ch : value) | |
encode<CharType, ByteIterator, SizeType>(ch, iter); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment