Skip to content

Instantly share code, notes, and snippets.

@codebrainz
Last active August 29, 2015 14:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save codebrainz/765ec3b211f93455da3f to your computer and use it in GitHub Desktop.
Save codebrainz/765ec3b211f93455da3f to your computer and use it in GitHub Desktop.
Byte encoder for some basic types
#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